/*
 * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package build.tools.javazic;

import java.util.StringTokenizer;

/**
 * RuleRec class represents one record of the Rule set.
 *
 * @since 1.4
 */
class RuleRec {
    private int fromYear;
    private int toYear;
    private String type;
    private Month inMonth;
    private RuleDay onDay;
    private Time atTime;
    private int save;
    private String letters;
    private String line;
    private boolean isLastRule;

    int getFromYear() {
        return fromYear;
    }

    int getToYear() {
        return toYear;
    }

    Month getMonth() {
        return inMonth;
    }

    int getMonthNum() {
        return inMonth.value();
    }

    RuleDay getDay() {
        return onDay;
    }

    Time getTime() {
        return atTime;
    }

    int getSave() {
        return save;
    }

    String getLine() {
        return line;
    }

    /**
     * Sets the line from the text file.
     * @param line the text of the line
     */
    void setLine(String line) {
        this.line = line;
    }

    /**
     * @return true if the rule type is "odd".
     */
    boolean isOdd() {
        return "odd".equals(type);
    }

    /**
     * @return true if the rule type is "even".
     */
    boolean isEven() {
        return "even".equals(type);
    }

    /**
     * Determines if this rule record is the last DST schedule rule.
     *
     * @return true if this rule record has "max" as TO (year).
     */
    boolean isLastRule() {
        return isLastRule;
    }

    /**
     * Determines if the unadjusted until time of the specified ZoneRec
     * is the same as the transition time of this rule in the same
     * year as the ZoneRec until year.
     *
     * @param zrec ZoneRec to compare to
     * @param save the amount of daylight saving in milliseconds
     * @param gmtOffset the GMT offset value in milliseconds
     * @return true if the unadjusted until time is the same as rule's
     * transition time.
     */
    boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) {
        long    until, transition;

        if (zrec.getUntilTime().getType() != atTime.getType()) {
            until = zrec.getLocalUntilTime(save, gmtOffset);
            transition = Time.getLocalTime(zrec.getUntilYear(),
                                           getMonth(),
                                           getDay(),
                                           save,
                                           gmtOffset,
                                           atTime);
        } else {
            until = zrec.getLocalUntilTime();
            transition = Time.getLocalTime(zrec.getUntilYear(),
                                           getMonth(),
                                           getDay(),
                                           atTime.getTime());
        }

        return until == transition;
    }

    /**
     * Parses a Rule line and returns a RuleRec object.
     *
     * @param tokens a StringTokenizer object that should contain a
     * token for the "FROM" field and the rest.
     * @return a RuleRec object.
     */
    static RuleRec parse(StringTokenizer tokens) {
        RuleRec rec = new RuleRec();
        try {
            // FROM
            String token = tokens.nextToken();
            try {
                rec.fromYear = Integer.parseInt(token);
            } catch (NumberFormatException e) {
                // it's not integer
                if ("min".equals(token) || "minimum".equals(token)) {
                    rec.fromYear = Zoneinfo.getMinYear();
                } else if ("max".equals(token) || "maximum".equals(token)) {
                    rec.fromYear = Zoneinfo.getMaxYear();
                } else {
                    Main.panic("invalid year value: "+token);
                }
            }

            // TO
            token = tokens.nextToken();
            rec.isLastRule = false;
            try {
                rec.toYear = Integer.parseInt(token);
            } catch (NumberFormatException e) {
                // it's not integer
                if ("min".equals(token) || "minimum".equals(token)) {
                    rec.fromYear = Zoneinfo.getMinYear();
                } else if ("max".equals(token) || "maximum".equals(token)) {
                    rec.toYear = Integer.MAX_VALUE;
                    rec.isLastRule = true;
                } else if ("only".equals(token)) {
                    rec.toYear = rec.fromYear;
                } else {
                    Main.panic("invalid year value: "+token);
                }
            }

            // TYPE
            rec.type = tokens.nextToken();

            // IN
            rec.inMonth = Month.parse(tokens.nextToken());

            // ON
            rec.onDay = RuleDay.parse(tokens.nextToken());

            // AT
            rec.atTime = Time.parse(tokens.nextToken());

            // SAVE
            rec.save = (int) Time.parse(tokens.nextToken()).getTime();

            // LETTER/S
            rec.letters = tokens.nextToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rec;
    }

    /**
     * Calculates the transition time of the given year under this rule.
     * @param year the year value
     * @param gmtOffset the GMT offset value in milliseconds
     * @param save the amount of daylight save time
     * @return the transition time in milliseconds of the given year in UTC.
     */
    long getTransitionTime(int year, int gmtOffset, int save) {
        long time = Time.getLocalTime(year, getMonth(),
                                      getDay(), atTime.getTime());
        if (atTime.isSTD()) {
            time -= gmtOffset;
        } else if (atTime.isWall()) {
            time -= gmtOffset + save;
        }
        return time;
    }

    private static int getInt(StringTokenizer tokens) {
        String token = tokens.nextToken();
        return Integer.parseInt(token);
    }
}
