/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * 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 com.android.calendarcommon2;

import android.text.TextUtils;
import android.util.Log;

import java.util.Calendar;
import java.util.HashMap;

/**
 * Event recurrence utility functions.
 */
public class EventRecurrence {
    private static String TAG = "EventRecur";

    public static final int SECONDLY = 1;
    public static final int MINUTELY = 2;
    public static final int HOURLY = 3;
    public static final int DAILY = 4;
    public static final int WEEKLY = 5;
    public static final int MONTHLY = 6;
    public static final int YEARLY = 7;

    public static final int SU = 0x00010000;
    public static final int MO = 0x00020000;
    public static final int TU = 0x00040000;
    public static final int WE = 0x00080000;
    public static final int TH = 0x00100000;
    public static final int FR = 0x00200000;
    public static final int SA = 0x00400000;

    public Time      startDate;     // set by setStartDate(), not parse()

    public int       freq;          // SECONDLY, MINUTELY, etc.
    public String    until;
    public int       count;
    public int       interval;
    public int       wkst;          // SU, MO, TU, etc.

    /* lists with zero entries may be null references */
    public int[]     bysecond;
    public int       bysecondCount;
    public int[]     byminute;
    public int       byminuteCount;
    public int[]     byhour;
    public int       byhourCount;
    public int[]     byday;
    public int[]     bydayNum;
    public int       bydayCount;
    public int[]     bymonthday;
    public int       bymonthdayCount;
    public int[]     byyearday;
    public int       byyeardayCount;
    public int[]     byweekno;
    public int       byweeknoCount;
    public int[]     bymonth;
    public int       bymonthCount;
    public int[]     bysetpos;
    public int       bysetposCount;

    /** maps a part string to a parser object */
    private static HashMap<String,PartParser> sParsePartMap;
    static {
        sParsePartMap = new HashMap<String,PartParser>();
        sParsePartMap.put("FREQ", new ParseFreq());
        sParsePartMap.put("UNTIL", new ParseUntil());
        sParsePartMap.put("COUNT", new ParseCount());
        sParsePartMap.put("INTERVAL", new ParseInterval());
        sParsePartMap.put("BYSECOND", new ParseBySecond());
        sParsePartMap.put("BYMINUTE", new ParseByMinute());
        sParsePartMap.put("BYHOUR", new ParseByHour());
        sParsePartMap.put("BYDAY", new ParseByDay());
        sParsePartMap.put("BYMONTHDAY", new ParseByMonthDay());
        sParsePartMap.put("BYYEARDAY", new ParseByYearDay());
        sParsePartMap.put("BYWEEKNO", new ParseByWeekNo());
        sParsePartMap.put("BYMONTH", new ParseByMonth());
        sParsePartMap.put("BYSETPOS", new ParseBySetPos());
        sParsePartMap.put("WKST", new ParseWkst());
    }

    /* values for bit vector that keeps track of what we have already seen */
    private static final int PARSED_FREQ = 1 << 0;
    private static final int PARSED_UNTIL = 1 << 1;
    private static final int PARSED_COUNT = 1 << 2;
    private static final int PARSED_INTERVAL = 1 << 3;
    private static final int PARSED_BYSECOND = 1 << 4;
    private static final int PARSED_BYMINUTE = 1 << 5;
    private static final int PARSED_BYHOUR = 1 << 6;
    private static final int PARSED_BYDAY = 1 << 7;
    private static final int PARSED_BYMONTHDAY = 1 << 8;
    private static final int PARSED_BYYEARDAY = 1 << 9;
    private static final int PARSED_BYWEEKNO = 1 << 10;
    private static final int PARSED_BYMONTH = 1 << 11;
    private static final int PARSED_BYSETPOS = 1 << 12;
    private static final int PARSED_WKST = 1 << 13;

    /** maps a FREQ value to an integer constant */
    private static final HashMap<String,Integer> sParseFreqMap = new HashMap<String,Integer>();
    static {
        sParseFreqMap.put("SECONDLY", SECONDLY);
        sParseFreqMap.put("MINUTELY", MINUTELY);
        sParseFreqMap.put("HOURLY", HOURLY);
        sParseFreqMap.put("DAILY", DAILY);
        sParseFreqMap.put("WEEKLY", WEEKLY);
        sParseFreqMap.put("MONTHLY", MONTHLY);
        sParseFreqMap.put("YEARLY", YEARLY);
    }

    /** maps a two-character weekday string to an integer constant */
    private static final HashMap<String,Integer> sParseWeekdayMap = new HashMap<String,Integer>();
    static {
        sParseWeekdayMap.put("SU", SU);
        sParseWeekdayMap.put("MO", MO);
        sParseWeekdayMap.put("TU", TU);
        sParseWeekdayMap.put("WE", WE);
        sParseWeekdayMap.put("TH", TH);
        sParseWeekdayMap.put("FR", FR);
        sParseWeekdayMap.put("SA", SA);
    }

    /** If set, allow lower-case recurrence rule strings.  Minor performance impact. */
    private static final boolean ALLOW_LOWER_CASE = true;

    /** If set, validate the value of UNTIL parts.  Minor performance impact. */
    private static final boolean VALIDATE_UNTIL = false;

    /** If set, require that only one of {UNTIL,COUNT} is present.  Breaks compat w/ old parser. */
    private static final boolean ONLY_ONE_UNTIL_COUNT = false;


    /**
     * Thrown when a recurrence string provided can not be parsed according
     * to RFC2445.
     */
    public static class InvalidFormatException extends RuntimeException {
        InvalidFormatException(String s) {
            super(s);
        }
    }


    public void setStartDate(Time date) {
        startDate = date;
    }

    /**
     * Converts one of the Calendar.SUNDAY constants to the SU, MO, etc.
     * constants.  btw, I think we should switch to those here too, to
     * get rid of this function, if possible.
     */
    public static int calendarDay2Day(int day)
    {
        switch (day)
        {
            case Calendar.SUNDAY:
                return SU;
            case Calendar.MONDAY:
                return MO;
            case Calendar.TUESDAY:
                return TU;
            case Calendar.WEDNESDAY:
                return WE;
            case Calendar.THURSDAY:
                return TH;
            case Calendar.FRIDAY:
                return FR;
            case Calendar.SATURDAY:
                return SA;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    public static int timeDay2Day(int day)
    {
        switch (day)
        {
            case Time.SUNDAY:
                return SU;
            case Time.MONDAY:
                return MO;
            case Time.TUESDAY:
                return TU;
            case Time.WEDNESDAY:
                return WE;
            case Time.THURSDAY:
                return TH;
            case Time.FRIDAY:
                return FR;
            case Time.SATURDAY:
                return SA;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }
    public static int day2TimeDay(int day)
    {
        switch (day)
        {
            case SU:
                return Time.SUNDAY;
            case MO:
                return Time.MONDAY;
            case TU:
                return Time.TUESDAY;
            case WE:
                return Time.WEDNESDAY;
            case TH:
                return Time.THURSDAY;
            case FR:
                return Time.FRIDAY;
            case SA:
                return Time.SATURDAY;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    /**
     * Converts one of the SU, MO, etc. constants to the Calendar.SUNDAY
     * constants.  btw, I think we should switch to those here too, to
     * get rid of this function, if possible.
     */
    public static int day2CalendarDay(int day)
    {
        switch (day)
        {
            case SU:
                return Calendar.SUNDAY;
            case MO:
                return Calendar.MONDAY;
            case TU:
                return Calendar.TUESDAY;
            case WE:
                return Calendar.WEDNESDAY;
            case TH:
                return Calendar.THURSDAY;
            case FR:
                return Calendar.FRIDAY;
            case SA:
                return Calendar.SATURDAY;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    /**
     * Converts one of the internal day constants (SU, MO, etc.) to the
     * two-letter string representing that constant.
     *
     * @param day one the internal constants SU, MO, etc.
     * @return the two-letter string for the day ("SU", "MO", etc.)
     *
     * @throws IllegalArgumentException Thrown if the day argument is not one of
     * the defined day constants.
     */
    private static String day2String(int day) {
        switch (day) {
        case SU:
            return "SU";
        case MO:
            return "MO";
        case TU:
            return "TU";
        case WE:
            return "WE";
        case TH:
            return "TH";
        case FR:
            return "FR";
        case SA:
            return "SA";
        default:
            throw new IllegalArgumentException("bad day argument: " + day);
        }
    }

    private static void appendNumbers(StringBuilder s, String label,
                                        int count, int[] values)
    {
        if (count > 0) {
            s.append(label);
            count--;
            for (int i=0; i<count; i++) {
                s.append(values[i]);
                s.append(",");
            }
            s.append(values[count]);
        }
    }

    private void appendByDay(StringBuilder s, int i)
    {
        int n = this.bydayNum[i];
        if (n != 0) {
            s.append(n);
        }

        String str = day2String(this.byday[i]);
        s.append(str);
    }

    @Override
    public String toString()
    {
        StringBuilder s = new StringBuilder();

        s.append("FREQ=");
        switch (this.freq)
        {
            case SECONDLY:
                s.append("SECONDLY");
                break;
            case MINUTELY:
                s.append("MINUTELY");
                break;
            case HOURLY:
                s.append("HOURLY");
                break;
            case DAILY:
                s.append("DAILY");
                break;
            case WEEKLY:
                s.append("WEEKLY");
                break;
            case MONTHLY:
                s.append("MONTHLY");
                break;
            case YEARLY:
                s.append("YEARLY");
                break;
        }

        if (!TextUtils.isEmpty(this.until)) {
            s.append(";UNTIL=");
            s.append(until);
        }

        if (this.count != 0) {
            s.append(";COUNT=");
            s.append(this.count);
        }

        if (this.interval != 0) {
            s.append(";INTERVAL=");
            s.append(this.interval);
        }

        if (this.wkst != 0) {
            s.append(";WKST=");
            s.append(day2String(this.wkst));
        }

        appendNumbers(s, ";BYSECOND=", this.bysecondCount, this.bysecond);
        appendNumbers(s, ";BYMINUTE=", this.byminuteCount, this.byminute);
        appendNumbers(s, ";BYSECOND=", this.byhourCount, this.byhour);

        // day
        int count = this.bydayCount;
        if (count > 0) {
            s.append(";BYDAY=");
            count--;
            for (int i=0; i<count; i++) {
                appendByDay(s, i);
                s.append(",");
            }
            appendByDay(s, count);
        }

        appendNumbers(s, ";BYMONTHDAY=", this.bymonthdayCount, this.bymonthday);
        appendNumbers(s, ";BYYEARDAY=", this.byyeardayCount, this.byyearday);
        appendNumbers(s, ";BYWEEKNO=", this.byweeknoCount, this.byweekno);
        appendNumbers(s, ";BYMONTH=", this.bymonthCount, this.bymonth);
        appendNumbers(s, ";BYSETPOS=", this.bysetposCount, this.bysetpos);

        return s.toString();
    }

    public boolean repeatsOnEveryWeekDay() {
        if (this.freq != WEEKLY) {
            return false;
        }

        int count = this.bydayCount;
        if (count != 5) {
            return false;
        }

        for (int i = 0 ; i < count ; i++) {
            int day = byday[i];
            if (day == SU || day == SA) {
                return false;
            }
        }

        return true;
    }

    /**
     * Determines whether this rule specifies a simple monthly rule by weekday, such as
     * "FREQ=MONTHLY;BYDAY=3TU" (the 3rd Tuesday of every month).
     * <p>
     * Negative days, e.g. "FREQ=MONTHLY;BYDAY=-1TU" (the last Tuesday of every month),
     * will cause "false" to be returned.
     * <p>
     * Rules that fire every week, such as "FREQ=MONTHLY;BYDAY=TU" (every Tuesday of every
     * month) will cause "false" to be returned.  (Note these are usually expressed as
     * WEEKLY rules, and hence are uncommon.)
     *
     * @return true if this rule is of the appropriate form
     */
    public boolean repeatsMonthlyOnDayCount() {
        if (this.freq != MONTHLY) {
            return false;
        }

        if (bydayCount != 1 || bymonthdayCount != 0) {
            return false;
        }

        if (bydayNum[0] <= 0) {
            return false;
        }

        return true;
    }

    /**
     * Determines whether two integer arrays contain identical elements.
     * <p>
     * The native implementation over-allocated the arrays (and may have stuff left over from
     * a previous run), so we can't just check the arrays -- the separately-maintained count
     * field also matters.  We assume that a null array will have a count of zero, and that the
     * array can hold as many elements as the associated count indicates.
     * <p>
     * TODO: replace this with Arrays.equals() when the old parser goes away.
     */
    private static boolean arraysEqual(int[] array1, int count1, int[] array2, int count2) {
        if (count1 != count2) {
            return false;
        }

        for (int i = 0; i < count1; i++) {
            if (array1[i] != array2[i])
                return false;
        }

        return true;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof EventRecurrence)) {
            return false;
        }

        EventRecurrence er = (EventRecurrence) obj;
        return  (startDate == null ?
                        er.startDate == null : startDate.compareTo(er.startDate) == 0) &&
                freq == er.freq &&
                (until == null ? er.until == null : until.equals(er.until)) &&
                count == er.count &&
                interval == er.interval &&
                wkst == er.wkst &&
                arraysEqual(bysecond, bysecondCount, er.bysecond, er.bysecondCount) &&
                arraysEqual(byminute, byminuteCount, er.byminute, er.byminuteCount) &&
                arraysEqual(byhour, byhourCount, er.byhour, er.byhourCount) &&
                arraysEqual(byday, bydayCount, er.byday, er.bydayCount) &&
                arraysEqual(bydayNum, bydayCount, er.bydayNum, er.bydayCount) &&
                arraysEqual(bymonthday, bymonthdayCount, er.bymonthday, er.bymonthdayCount) &&
                arraysEqual(byyearday, byyeardayCount, er.byyearday, er.byyeardayCount) &&
                arraysEqual(byweekno, byweeknoCount, er.byweekno, er.byweeknoCount) &&
                arraysEqual(bymonth, bymonthCount, er.bymonth, er.bymonthCount) &&
                arraysEqual(bysetpos, bysetposCount, er.bysetpos, er.bysetposCount);
    }

    @Override public int hashCode() {
        // We overrode equals, so we must override hashCode().  Nobody seems to need this though.
        throw new UnsupportedOperationException();
    }

    /**
     * Resets parser-modified fields to their initial state.  Does not alter startDate.
     * <p>
     * The original parser always set all of the "count" fields, "wkst", and "until",
     * essentially allowing the same object to be used multiple times by calling parse().
     * It's unclear whether this behavior was intentional.  For now, be paranoid and
     * preserve the existing behavior by resetting the fields.
     * <p>
     * We don't need to touch the integer arrays; they will either be ignored or
     * overwritten.  The "startDate" field is not set by the parser, so we ignore it here.
     */
    private void resetFields() {
        until = null;
        freq = count = interval = bysecondCount = byminuteCount = byhourCount =
            bydayCount = bymonthdayCount = byyeardayCount = byweeknoCount = bymonthCount =
            bysetposCount = 0;
    }

    /**
     * Parses an rfc2445 recurrence rule string into its component pieces.  Attempting to parse
     * malformed input will result in an EventRecurrence.InvalidFormatException.
     *
     * @param recur The recurrence rule to parse (in un-folded form).
     */
    public void parse(String recur) {
        /*
         * From RFC 2445 section 4.3.10:
         *
         * recur = "FREQ"=freq *(
         *       ; either UNTIL or COUNT may appear in a 'recur',
         *       ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
         *
         *       ( ";" "UNTIL" "=" enddate ) /
         *       ( ";" "COUNT" "=" 1*DIGIT ) /
         *
         *       ; the rest of these keywords are optional,
         *       ; but MUST NOT occur more than once
         *
         *       ( ";" "INTERVAL" "=" 1*DIGIT )          /
         *       ( ";" "BYSECOND" "=" byseclist )        /
         *       ( ";" "BYMINUTE" "=" byminlist )        /
         *       ( ";" "BYHOUR" "=" byhrlist )           /
         *       ( ";" "BYDAY" "=" bywdaylist )          /
         *       ( ";" "BYMONTHDAY" "=" bymodaylist )    /
         *       ( ";" "BYYEARDAY" "=" byyrdaylist )     /
         *       ( ";" "BYWEEKNO" "=" bywknolist )       /
         *       ( ";" "BYMONTH" "=" bymolist )          /
         *       ( ";" "BYSETPOS" "=" bysplist )         /
         *       ( ";" "WKST" "=" weekday )              /
         *       ( ";" x-name "=" text )
         *       )
         *
         *  The rule parts are not ordered in any particular sequence.
         *
         * Examples:
         *   FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
         *   FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8
         *
         * Strategy:
         * (1) Split the string at ';' boundaries to get an array of rule "parts".
         * (2) For each part, find substrings for left/right sides of '=' (name/value).
         * (3) Call a <name>-specific parsing function to parse the <value> into an
         *     output field.
         *
         * By keeping track of which names we've seen in a bit vector, we can verify the
         * constraints indicated above (FREQ appears first, none of them appear more than once --
         * though x-[name] would require special treatment), and we have either UNTIL or COUNT
         * but not both.
         *
         * In general, RFC 2445 property names (e.g. "FREQ") and enumerations ("TU") must
         * be handled in a case-insensitive fashion, but case may be significant for other
         * properties.  We don't have any case-sensitive values in RRULE, except possibly
         * for the custom "X-" properties, but we ignore those anyway.  Thus, we can trivially
         * convert the entire string to upper case and then use simple comparisons.
         *
         * Differences from previous version:
         * - allows lower-case property and enumeration values [optional]
         * - enforces that FREQ appears first
         * - enforces that only one of UNTIL and COUNT may be specified
         * - allows (but ignores) X-* parts
         * - improved validation on various values (e.g. UNTIL timestamps)
         * - error messages are more specific
         *
         * TODO: enforce additional constraints listed in RFC 5545, notably the "N/A" entries
         * in section 3.3.10.  For example, if FREQ=WEEKLY, we should reject a rule that
         * includes a BYMONTHDAY part.
         */

        /* TODO: replace with "if (freq != 0) throw" if nothing requires this */
        resetFields();

        int parseFlags = 0;
        String[] parts;
        if (ALLOW_LOWER_CASE) {
            parts = recur.toUpperCase().split(";");
        } else {
            parts = recur.split(";");
        }
        for (String part : parts) {
            // allow empty part (e.g., double semicolon ";;")
            if (TextUtils.isEmpty(part)) {
                continue;
            }
            int equalIndex = part.indexOf('=');
            if (equalIndex <= 0) {
                /* no '=' or no LHS */
                throw new InvalidFormatException("Missing LHS in " + part);
            }

            String lhs = part.substring(0, equalIndex);
            String rhs = part.substring(equalIndex + 1);
            if (rhs.length() == 0) {
                throw new InvalidFormatException("Missing RHS in " + part);
            }

            /*
             * In lieu of a "switch" statement that allows string arguments, we use a
             * map from strings to parsing functions.
             */
            PartParser parser = sParsePartMap.get(lhs);
            if (parser == null) {
                if (lhs.startsWith("X-")) {
                    //Log.d(TAG, "Ignoring custom part " + lhs);
                    continue;
                }
                throw new InvalidFormatException("Couldn't find parser for " + lhs);
            } else {
                int flag = parser.parsePart(rhs, this);
                if ((parseFlags & flag) != 0) {
                    throw new InvalidFormatException("Part " + lhs + " was specified twice");
                }
                parseFlags |= flag;
            }
        }

        // If not specified, week starts on Monday.
        if ((parseFlags & PARSED_WKST) == 0) {
            wkst = MO;
        }

        // FREQ is mandatory.
        if ((parseFlags & PARSED_FREQ) == 0) {
            throw new InvalidFormatException("Must specify a FREQ value");
        }

        // Can't have both UNTIL and COUNT.
        if ((parseFlags & (PARSED_UNTIL | PARSED_COUNT)) == (PARSED_UNTIL | PARSED_COUNT)) {
            if (ONLY_ONE_UNTIL_COUNT) {
                throw new InvalidFormatException("Must not specify both UNTIL and COUNT: " + recur);
            } else {
                Log.w(TAG, "Warning: rrule has both UNTIL and COUNT: " + recur);
            }
        }
    }

    /**
     * Base class for the RRULE part parsers.
     */
    abstract static class PartParser {
        /**
         * Parses a single part.
         *
         * @param value The right-hand-side of the part.
         * @param er The EventRecurrence into which the result is stored.
         * @return A bit value indicating which part was parsed.
         */
        public abstract int parsePart(String value, EventRecurrence er);

        /**
         * Parses an integer, with range-checking.
         *
         * @param str The string to parse.
         * @param minVal Minimum allowed value.
         * @param maxVal Maximum allowed value.
         * @param allowZero Is 0 allowed?
         * @return The parsed value.
         */
        public static int parseIntRange(String str, int minVal, int maxVal, boolean allowZero) {
            try {
                if (str.charAt(0) == '+') {
                    // Integer.parseInt does not allow a leading '+', so skip it manually.
                    str = str.substring(1);
                }
                int val = Integer.parseInt(str);
                if (val < minVal || val > maxVal || (val == 0 && !allowZero)) {
                    throw new InvalidFormatException("Integer value out of range: " + str);
                }
                return val;
            } catch (NumberFormatException nfe) {
                throw new InvalidFormatException("Invalid integer value: " + str);
            }
        }

        /**
         * Parses a comma-separated list of integers, with range-checking.
         *
         * @param listStr The string to parse.
         * @param minVal Minimum allowed value.
         * @param maxVal Maximum allowed value.
         * @param allowZero Is 0 allowed?
         * @return A new array with values, sized to hold the exact number of elements.
         */
        public static int[] parseNumberList(String listStr, int minVal, int maxVal,
                boolean allowZero) {
            int[] values;

            if (listStr.indexOf(",") < 0) {
                // Common case: only one entry, skip split() overhead.
                values = new int[1];
                values[0] = parseIntRange(listStr, minVal, maxVal, allowZero);
            } else {
                String[] valueStrs = listStr.split(",");
                int len = valueStrs.length;
                values = new int[len];
                for (int i = 0; i < len; i++) {
                    values[i] = parseIntRange(valueStrs[i], minVal, maxVal, allowZero);
                }
            }
            return values;
        }
   }

    /** parses FREQ={SECONDLY,MINUTELY,...} */
    private static class ParseFreq extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            Integer freq = sParseFreqMap.get(value);
            if (freq == null) {
                throw new InvalidFormatException("Invalid FREQ value: " + value);
            }
            er.freq = freq;
            return PARSED_FREQ;
        }
    }
    /** parses UNTIL=enddate, e.g. "19970829T021400" */
    private static class ParseUntil extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            if (VALIDATE_UNTIL) {
                try {
                    // Parse the time to validate it.  The result isn't retained.
                    Time until = new Time();
                    until.parse(value);
                } catch (IllegalArgumentException iae) {
                    throw new InvalidFormatException("Invalid UNTIL value: " + value);
                }
            }
            er.until = value;
            return PARSED_UNTIL;
        }
    }
    /** parses COUNT=[non-negative-integer] */
    private static class ParseCount extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            er.count = parseIntRange(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            if (er.count < 0) {
                Log.d(TAG, "Invalid Count. Forcing COUNT to 1 from " + value);
                er.count = 1; // invalid count. assume one time recurrence.
            }
            return PARSED_COUNT;
        }
    }
    /** parses INTERVAL=[non-negative-integer] */
    private static class ParseInterval extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            er.interval = parseIntRange(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            if (er.interval < 1) {
                Log.d(TAG, "Invalid Interval. Forcing INTERVAL to 1 from " + value);
                er.interval = 1;
            }
            return PARSED_INTERVAL;
        }
    }
    /** parses BYSECOND=byseclist */
    private static class ParseBySecond extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bysecond = parseNumberList(value, 0, 59, true);
            er.bysecond = bysecond;
            er.bysecondCount = bysecond.length;
            return PARSED_BYSECOND;
        }
    }
    /** parses BYMINUTE=byminlist */
    private static class ParseByMinute extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byminute = parseNumberList(value, 0, 59, true);
            er.byminute = byminute;
            er.byminuteCount = byminute.length;
            return PARSED_BYMINUTE;
        }
    }
    /** parses BYHOUR=byhrlist */
    private static class ParseByHour extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byhour = parseNumberList(value, 0, 23, true);
            er.byhour = byhour;
            er.byhourCount = byhour.length;
            return PARSED_BYHOUR;
        }
    }
    /** parses BYDAY=bywdaylist, e.g. "1SU,-1SU" */
    private static class ParseByDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byday;
            int[] bydayNum;
            int bydayCount;

            if (value.indexOf(",") < 0) {
                /* only one entry, skip split() overhead */
                bydayCount = 1;
                byday = new int[1];
                bydayNum = new int[1];
                parseWday(value, byday, bydayNum, 0);
            } else {
                String[] wdays = value.split(",");
                int len = wdays.length;
                bydayCount = len;
                byday = new int[len];
                bydayNum = new int[len];
                for (int i = 0; i < len; i++) {
                    parseWday(wdays[i], byday, bydayNum, i);
                }
            }
            er.byday = byday;
            er.bydayNum = bydayNum;
            er.bydayCount = bydayCount;
            return PARSED_BYDAY;
        }

        /** parses [int]weekday, putting the pieces into parallel array entries */
        private static void parseWday(String str, int[] byday, int[] bydayNum, int index) {
            int wdayStrStart = str.length() - 2;
            String wdayStr;

            if (wdayStrStart > 0) {
                /* number is included; parse it out and advance to weekday */
                String numPart = str.substring(0, wdayStrStart);
                int num = parseIntRange(numPart, -53, 53, false);
                bydayNum[index] = num;
                wdayStr = str.substring(wdayStrStart);
            } else {
                /* just the weekday string */
                wdayStr = str;
            }
            Integer wday = sParseWeekdayMap.get(wdayStr);
            if (wday == null) {
                throw new InvalidFormatException("Invalid BYDAY value: " + str);
            }
            byday[index] = wday;
        }
    }
    /** parses BYMONTHDAY=bymodaylist */
    private static class ParseByMonthDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bymonthday = parseNumberList(value, -31, 31, false);
            er.bymonthday = bymonthday;
            er.bymonthdayCount = bymonthday.length;
            return PARSED_BYMONTHDAY;
        }
    }
    /** parses BYYEARDAY=byyrdaylist */
    private static class ParseByYearDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byyearday = parseNumberList(value, -366, 366, false);
            er.byyearday = byyearday;
            er.byyeardayCount = byyearday.length;
            return PARSED_BYYEARDAY;
        }
    }
    /** parses BYWEEKNO=bywknolist */
    private static class ParseByWeekNo extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byweekno = parseNumberList(value, -53, 53, false);
            er.byweekno = byweekno;
            er.byweeknoCount = byweekno.length;
            return PARSED_BYWEEKNO;
        }
    }
    /** parses BYMONTH=bymolist */
    private static class ParseByMonth extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bymonth = parseNumberList(value, 1, 12, false);
            er.bymonth = bymonth;
            er.bymonthCount = bymonth.length;
            return PARSED_BYMONTH;
        }
    }
    /** parses BYSETPOS=bysplist */
    private static class ParseBySetPos extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bysetpos = parseNumberList(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            er.bysetpos = bysetpos;
            er.bysetposCount = bysetpos.length;
            return PARSED_BYSETPOS;
        }
    }
    /** parses WKST={SU,MO,...} */
    private static class ParseWkst extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            Integer wkst = sParseWeekdayMap.get(value);
            if (wkst == null) {
                throw new InvalidFormatException("Invalid WKST value: " + value);
            }
            er.wkst = wkst;
            return PARSED_WKST;
        }
    }
}
