/*
 * Copyright (C) 2008-2009 GLAD!! (ITO Yoshiichi)
 *
 * 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 jp.sourceforge.glad.calendar.joda.chrono;

import java.util.Locale;

import jp.sourceforge.glad.calendar.era.JapaneseEra;

import org.joda.time.DateTimeFieldType;
import org.joda.time.DurationField;
import org.joda.time.DurationFieldType;
import org.joda.time.field.BaseDateTimeField;
import org.joda.time.field.UnsupportedDurationField;

/**
 * 
 * 
 * @author GLAD!!
 */
class JapaneseEraDateTimeField extends BaseDateTimeField {

    final JapaneseChronology iChronology;

    /**
     * Restricted constructor
     */
    JapaneseEraDateTimeField(JapaneseChronology chronology) {
        super(DateTimeFieldType.era());
        iChronology = chronology;
    }

    public boolean isLenient() {
        return false;
    }

    // Main access API
    //------------------------------------------------------------------------

    /**
     * Get the Era component of the specified time instant.
     * 
     * @param instant  the time instant in millis to query.
     */
    public int get(long instant) {
        return iChronology.getEra(instant);
    }

    @Override
    public String getAsText(int era, Locale locale) {
        return JapaneseLocaleSymbols.forLocale(locale).eraToText(era);
    }

    @Override
    public String getAsShortText(int era, Locale locale) {
        return JapaneseLocaleSymbols.forLocale(locale).eraToShortText(era);
    }

    /**
     * Set the Era component of the specified time instant.
     * 
     * @param instant  the time instant in millis to update.
     * @param era  the era to update the time to.
     * @return the updated time instant.
     * @throws IllegalArgumentException  if era is invalid.
     */
    public long set(long instant, int era) {
        return iChronology.setEra(instant, era);
    }

    @Override
    protected int convertText(String text, Locale locale) {
        return JapaneseLocaleSymbols.forLocale(locale).textToEra(text);
    }

    // Extra information API
    //------------------------------------------------------------------------

    public DurationField getDurationField() {
        return UnsupportedDurationField.getInstance(DurationFieldType.eras());
    }

    public DurationField getRangeDurationField() {
        return null;
    }

    public int getMinimumValue() {
        return iChronology.getMinEra();
    }

    public int getMaximumValue() {
        return iChronology.getMaxEra();
    }

    @Override
    public int getMaximumTextLength(Locale locale) {
        return JapaneseLocaleSymbols.forLocale(locale).getMaxEraLength();
    }

    @Override
    public int getMaximumShortTextLength(Locale locale) {
        return JapaneseLocaleSymbols.forLocale(locale).getMaxShortEraLength();
    }

    // Calculation API
    //------------------------------------------------------------------------

    public long roundFloor(long instant) {
        JapaneseEra era = iChronology.getJapaneseEra(instant);
        if (era.getId() == getMinimumValue()) {
            return Long.MIN_VALUE;
        }
        int year  = era.getSinceYear();
        int month = era.getSinceMonth();
        int day   = era.getSinceDay();
        return iChronology.getDateTimeMillis(year, month, day, 0);
    }

    @Override
    public long roundCeiling(long instant) {
        int era = iChronology.getEra(instant);
        if (era == getMaximumValue()) {
            return Long.MAX_VALUE;
        }
        JapaneseEra nextEra = JapaneseEra.getInstance(era + 1);
        int year  = nextEra.getSinceYear();
        int month = nextEra.getSinceMonth();
        int day   = nextEra.getSinceDay();
        return iChronology.getDateTimeMillis(year, month, day, 0);
    }

    @Override
    public long roundHalfFloor(long instant) {
        return roundFloor(instant);
    }

    @Override
    public long roundHalfCeiling(long instant) {
        return roundFloor(instant);
    }

    @Override
    public long roundHalfEven(long instant) {
        return roundFloor(instant);
    }

}
