/* UtilLib - Copyright (c) 2016-2024 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.primitives;

import java.io.Serializable;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.Date;
import net.mapeadores.util.text.DateFormatBundle;


/**
 *
 * @author Vincent Calame
 */
public final class FuzzyDate implements Serializable, Comparable<FuzzyDate> {

    public static final short YEAR_TYPE = 1;
    public static final short HALFYEAR_TYPE = 2;
    public static final short QUARTER_TYPE = 3;
    public static final short MONTH_TYPE = 4;
    public static final short DAY_TYPE = 5;
    private static final long serialVersionUID = 1L;
    private final int intValue;

    private FuzzyDate(int intValue) {
        this.intValue = intValue;
    }

    public short getType() {
        return FuzzyDateInteger.getType(intValue);
    }

    @Override
    public int hashCode() {
        return intValue;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }
        if (other.getClass() != this.getClass()) {
            return false;
        }
        FuzzyDate otherDate = (FuzzyDate) other;
        return (this.intValue == otherDate.intValue);
    }

    @Override
    public int compareTo(FuzzyDate anotherDate) {
        int thisVal = this.intValue;
        int anotherVal = anotherDate.intValue;
        return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
    }

    @Override
    public String toString() {
        return FuzzyDateInteger.toString(intValue);
    }

    public String toSortString() {
        return FuzzyDateInteger.toSortString(intValue);
    }

    public String toISOString() {
        return FuzzyDateInteger.toISOString(intValue, false);
    }

    public String toISOString(boolean lastDate) {
        return FuzzyDateInteger.toISOString(intValue, lastDate);
    }

    public String toMonthString(boolean lastMonth) {
        return FuzzyDateInteger.toMonthString(intValue, lastMonth);
    }

    public String getDateLitteral(DateFormatBundle dateFormatBundle) {
        return FuzzyDateInteger.getDateLitteral(intValue, dateFormatBundle);
    }

    public LocalDate toLocalDate(boolean lastDay) {
        return FuzzyDateInteger.toLocaleDate(intValue, lastDay);
    }

    public FuzzyDate truncate(short type) {
        return new FuzzyDate(FuzzyDateInteger.truncate(intValue, type));
    }

    public Date toDate() {
        return FuzzyDateInteger.toDate(intValue);
    }

    public int getYear() {
        return FuzzyDateInteger.getYear(intValue);
    }

    public int getHalfYear() {
        return FuzzyDateInteger.getHalfYear(intValue);
    }

    public int getQuarter() {
        return FuzzyDateInteger.getQuarter(intValue);
    }

    public int getMonth() {
        return FuzzyDateInteger.getMonth(intValue);
    }

    public int getDay() {
        return FuzzyDateInteger.getDay(intValue);
    }

    public FuzzyDate roll(int dayAmount) {
        return new FuzzyDate(FuzzyDateInteger.roll(intValue, dayAmount));
    }

    public static int toInt(FuzzyDate fuzzyDate) {
        return fuzzyDate.intValue;
    }

    public static FuzzyDate fromInt(int dateInt) {
        return new FuzzyDate(dateInt);
    }

    public static FuzzyDate parse(String s) throws ParseException {
        int intValue = FuzzyDateInteger.parse(s);
        return new FuzzyDate(intValue);
    }

    public static FuzzyDate parse(String s, DateFormatBundle dateFormatBundle) throws ParseException {
        return new FuzzyDate(FuzzyDateInteger.parse(s, dateFormatBundle));
    }

    public static FuzzyDate fromYear(int year) {
        return new FuzzyDate(FuzzyDateInteger.fromYear(year));
    }

    public static FuzzyDate fromHalfYear(int year, int halfyear) {
        return new FuzzyDate(FuzzyDateInteger.fromHalfYear(year, halfyear));
    }

    public static FuzzyDate fromQuarter(int year, int quarter) {
        return new FuzzyDate(FuzzyDateInteger.fromQuarter(year, quarter));
    }

    public static FuzzyDate fromMonth(int year, int month) {
        return new FuzzyDate(FuzzyDateInteger.fromMonth(year, month));
    }

    public static FuzzyDate fromDay(int year, int month, int day) {
        return new FuzzyDate(FuzzyDateInteger.fromDay(year, month, day));
    }

    public static FuzzyDate fromDate(Date date) {
        return new FuzzyDate(FuzzyDateInteger.fromDate(date));
    }

    public static int compare(FuzzyDate date1, FuzzyDate date2) {
        if (date1 != null) {
            if (date2 == null) {
                return 1;
            } else {
                return date1.compareTo(date2);
            }
        } else if (date2 != null) {
            return -1;
        } else {
            return 0;
        }
    }

    public static FuzzyDate max(FuzzyDate date1, FuzzyDate date2) {
        int comp = compare(date1, date2);
        if (comp < 0) {
            return date2;
        } else {
            return date1;
        }
    }

    public static FuzzyDate min(FuzzyDate date1, FuzzyDate date2) {
        int comp = compare(date1, date2);
        if (comp > 0) {
            return date2;
        } else {
            return date1;
        }
    }

    public static FuzzyDate current() {
        return new FuzzyDate(FuzzyDateInteger.current());
    }


}
