package com.ejie.ab79.comun;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.springframework.context.i18n.LocaleContextHolder;

import com.ejie.ab79.comun.Constantes;

/**
 * Librer�a de ayuda para las fechas.
 * 
 *  
 */

public class UtilDate implements Serializable {
	private static final long serialVersionUID = -2475753367190285685L;
	private static final String[] MESES_EUS = { "urtarrila", "otsaila", "martxoa", "apirila", "maiatza", "ekaina",
			"uztaila", "abuztua", "iraila", "urria", "azaroa", "abendua" };

	// private static final DateFormat FECHACORTA_NOBARRA_FORMAT_EU = new
	// SimpleDateFormat("yyyyMMdd");
	private static final String FECHACORTA_NOBARRA_FORMAT_EU = "yyyyMMdd";

	/**
	 * Constructor
	 */
	private UtilDate() {
		super();
	}

	/**
	 * Transforma una String tipo dd/MM/yyyy a java.util.Date.
	 * 
	 * @param fecha
	 *            String
	 * @return fecha Date
	 */
	@SuppressWarnings(value = "deprecation")
	public static Date convertirStringEnFecha(String fecha) {
		if (fecha != null && !fecha.equals("")) {
			String fechas[] = fecha.split("/");
			if (LocaleContextHolder.getLocale().toString().equals("es")) {
				return new Date(Integer.parseInt(fechas[2]) - Constantes.MAGIC_NUMBER_1900,
						Integer.parseInt(fechas[1]) - 1, Integer.parseInt(fechas[0]));
			} else {
				return new Date(Integer.parseInt(fechas[0]) - Constantes.MAGIC_NUMBER_1900,
						Integer.parseInt(fechas[1]) - 1, Integer.parseInt(fechas[2]));
			}
		} else {
			return new Date();
		}
	}

	/**
	 * Transforma una String tipo dd/MM/yyyy a java.util.Date.
	 * 
	 * @param fecha
	 *            String
	 * @return fecha Date
	 */
	@SuppressWarnings(value = "deprecation")
	public static Date convertirStringEnFechaNulable(String fecha) {
		if (fecha != null && !fecha.equals("")) {
			String fechas[] = fecha.split("/");
			if (LocaleContextHolder.getLocale().toString().equals("es")) {
				return new Date(Integer.parseInt(fechas[2]) - Constantes.MAGIC_NUMBER_1900,
						Integer.parseInt(fechas[1]) - 1, Integer.parseInt(fechas[0]));
			} else {
				return new Date(Integer.parseInt(fechas[0]) - Constantes.MAGIC_NUMBER_1900,
						Integer.parseInt(fechas[1]) - 1, Integer.parseInt(fechas[2]));
			}
		} else {
			return null;
		}
	}

	/**
	 * Devuelve una java.util.Date a String en formato dd/MM/yyyy o yyyy/MM/dd
	 * dependiendo de si est� en castellano o en euskera.
	 * 
	 * @param fecha
	 *            Date
	 * @return fecha String
	 */
	public static String convertirFechaEnString(Date fecha) {
		if (fecha != null) {
			if (LocaleContextHolder.getLocale().toString().equals("es")) {
				return (new SimpleDateFormat("dd/MM/yyyy")).format(fecha);
			} else {
				return (new SimpleDateFormat("yyyy/MM/dd")).format(fecha);
			}
		} else {
			return "";
		}
	}

	/**
	 * Devuelve la fecha pasada por parametro en formato yyyy-MM-dd HH:mm:ss
	 * 
	 * @param fecha
	 *            Date
	 * @return fecha String
	 */
	public static String convertirEnFechaConHora(Date fecha) {
		if (fecha != null) {
			if ("es".equalsIgnoreCase(LocaleContextHolder.getLocale().toString())) {
				return (new SimpleDateFormat("dd/MM/yyyy HH:mm:ss")).format(fecha);
			} else {
				return (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(fecha);
			}
		} else {
			return "";
		}
	}

	/**
	 * Transforma una java.util.Date a String en formato extendido dependiendo
	 * de si est� en castellano o en euskera.
	 * 
	 * @param fecha
	 *            Date
	 * @return fecha String
	 */
	public static String convertirFechaEnStringExt(Date fecha) {
		return UtilDate.convertirFechaEnStringExt(fecha, LocaleContextHolder.getLocale());
	}

	/**
	 * Transforma una java.util.Date a String en formato extendido dependiendo
	 * de si est� en castellano o en euskera.
	 * 
	 * @param fecha
	 *            Date
	 * @param locale
	 *            Locale
	 * @return fecha String
	 */
	public static String convertirFechaEnStringExt(Date fecha, Locale locale) {
		if (fecha != null) {
			SimpleDateFormat formato = null;

			if (locale.getLanguage().equals("es")) {
				formato = new SimpleDateFormat("d 'de' MMMM 'de' yyyy", new Locale("es", "ES"));
			} else {
				// Java Locale no soporta Euskera as� que se formatean los
				// meses
				// a mano.
				Calendar cal = Calendar.getInstance();
				cal.setTime(fecha);
				int month = cal.get(Calendar.MONTH);
				formato = new SimpleDateFormat("yyyy'ko' '" + UtilDate.MESES_EUS[month] + "ren' d",
						new Locale("eu", "ES"));
			}
			return formato.format(fecha);
		} else {
			return "";
		}
	}

	/**
	 * Transforma una String tipo dd/MM/yyyy o yyyy/MM/dd a dd/MM/yyyy.
	 * 
	 * @param fecha
	 *            String
	 * @return fecha String
	 */
	public static String convertirStringEnStringFormateado(String fecha) {
		String fechaAux = fecha;
		if (fechaAux != null && !fechaAux.equals("")) {
			String fechas[] = fechaAux.split("/");
			if (fechas[0].length() == Constantes.MAGIC_NUMBER_4) {
				fechaAux = fechas[2] + "/" + fechas[1] + "/" + fechas[0];
			}
			return fechaAux;
		}
		return "";
	}

	/**
	 * 
	 * @param anyo
	 *            int
	 * 
	 * @return Date
	 */
	public static Date obtenerFechaPorAnyo(int anyo) {

		// Instanciamos el objeto Calendar
		Calendar calendar = Calendar.getInstance();
		calendar.set(anyo, calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
		return calendar.getTime();
	}

	/**
	 * Devuelve un string con la fecha pasada como parametro en formato corto.
	 * 
	 * @param fecha
	 *            Date
	 * 
	 * @return String: string con la fecha en formato AAAAMMDD.
	 * 
	 * @throws Exception
	 *             Exception
	 */
	public static String fncObtenerFechaYYYYMMDD(Date fecha) throws Exception {
		DateFormat formatoFechaCorta = new SimpleDateFormat(UtilDate.FECHACORTA_NOBARRA_FORMAT_EU);

		return formatoFechaCorta.format(fecha);
	}// Fin fncObtenerFechaSistemaCorta

	/**
	 * Fomateo general de miles y decimales al idioma ES
	 * 
	 * @param pattern
	 *            a cumplir
	 * @param value
	 *            double
	 * @param loc
	 *            locale, en nuestro caso new Locale("es", "ES")
	 * @return String valor formateado
	 */
	private static String localizedFormat(String pattern, double value, Locale loc) {
		NumberFormat nf = NumberFormat.getNumberInstance(loc);
		DecimalFormat df = (DecimalFormat) nf;
		df.applyPattern(pattern);
		return df.format(value);
	}

	/**
	 * Formatear valores de base de datos para que cumplan ###,##0.00 y
	 * aplicandose el locale ES
	 * 
	 * @param valor
	 *            BigDecimal
	 * @return String
	 */
	public static String formatearMiles(BigDecimal valor) {
		if (valor != null) {
			return localizedFormat("###,##0.00", valor.doubleValue(), new Locale("es", "ES"));
		} else
			return "";
	}

}
