/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package woolpack.convert;

import java.text.Format;
import java.util.Collection;
import java.util.regex.Pattern;

import woolpack.fn.Fn;
import woolpack.fn.FnUtils;

/**
 * ユーティリティです。
 * 型推論で表記を簡略するためのスタティックメソッドと変数を含みます。
 * 
 * @author nakamura
 *
 */
public final class ConvertUtils {

	public static final ToBigDecimalConverter<RuntimeException> TO_BIG_DECIMAL = new ToBigDecimalConverter<RuntimeException>();
	public static final ToBigIntegerConverter<RuntimeException> TO_BIG_INTEGER = new ToBigIntegerConverter<RuntimeException>();
	public static final ToByteConverter<RuntimeException> TO_BYTE = new ToByteConverter<RuntimeException>();
	public static final ToDoubleConverter<RuntimeException> TO_DOUBLE = new ToDoubleConverter<RuntimeException>();
	public static final ToFloatConverter<RuntimeException> TO_FLOAT = new ToFloatConverter<RuntimeException>();
	public static final ToIntegerConverter<RuntimeException> TO_INTEGER = new ToIntegerConverter<RuntimeException>();
	public static final ToLongConverter<RuntimeException> TO_LONG = new ToLongConverter<RuntimeException>();
	public static final ToShortConverter<RuntimeException> TO_SHORT = new ToShortConverter<RuntimeException>();
	public static final ToSqlDateConverter<RuntimeException> TO_SQL_DATE = new ToSqlDateConverter<RuntimeException>();
	public static final ToTimeConverter<RuntimeException> TO_TIME = new ToTimeConverter<RuntimeException>();
	public static final ToTimestampConverter<RuntimeException> TO_TIMESTAMP = new ToTimestampConverter<RuntimeException>();
	public static final ToCalendarConverter<RuntimeException> TO_CALENDAR = new ToCalendarConverter<RuntimeException>();
	public static final ToStringConverter<RuntimeException> TO_STRING = new ToStringConverter<RuntimeException>();
	
	private ConvertUtils() {
	}
	
	public static <K> KeySetGetter<K, RuntimeException> keySet() {
		return new KeySetGetter<K, RuntimeException>();
	}
	
	public static CloneFormatFactory<RuntimeException> formatFactory(final Format format) {
		return new CloneFormatFactory<RuntimeException>(format);
	}
	
	public static <E extends Exception> FormatConverter<E> format(
			final Fn<?, ? extends Format, ? extends E> formatFactory) {
		return new FormatConverter<E>(formatFactory);
	}
	
	public static NetMaskConverter<RuntimeException> netMask(final String netMask) {
		return new NetMaskConverter<RuntimeException>(netMask);
	}
	
	public static ParseConverter parse(final Fn<?, ? extends Format, ? extends Exception> formatFactory) {
		return new ParseConverter(formatFactory);
	}
	
	public static RegExpConverter<RuntimeException> convertRegExp(
			final Pattern pattern,
			final String replacement) {
		return new RegExpConverter<RuntimeException>(pattern, replacement);
	}
	
	public static <C, R, E extends Exception> TrysFn<C, R, E> trys(
			final Iterable<? extends Fn<? super C, ? extends R, ? extends Exception>> iterable,
			final Fn<? super Exception, ?, ? extends E> errorFn,
			final Fn<? super Exception, ? extends R, ? extends E> finalFn) {
		return new TrysFn<C, R, E>(iterable, errorFn, finalFn);
	}
	
	public static <C, R> TrysFn<C, R, IllegalStateException> trys(
			final Iterable<? extends Fn<? super C, ? extends R, ? extends Exception>> iterable) {
		return new TrysFn<C, R, IllegalStateException>(
				iterable,
				FnUtils.<Exception, R, IllegalStateException>fixThrows(null),
				new Fn<Exception, R, IllegalStateException>() {
					public R exec(final Exception c) throws IllegalStateException {
						throw new IllegalStateException(c);
					}
				});
	}
	
	public static RetainKeys<RuntimeException> retainKeys(final Collection<?> collection) {
		return new RetainKeys<RuntimeException>(collection);
	}
}
