/*
 * Copyright (C) 2008 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.deskclock;

import android.content.Context;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.text.DateFormatSymbols;


public class TimePicker extends TimerSetupView implements Button.OnClickListener{

    private TextView mAmPmLabel;
    private String[] mAmpm;
    private final String mNoAmPmLabel;
    private int mAmPmState;
    private Button mSetButton;
    private final boolean mIs24HoursMode = Alarms.get24HourMode(mContext);

    private static final int AMPM_NOT_SELECTED = 0;
    private static final int PM_SELECTED = 1;
    private static final int AM_SELECTED = 2;
    private static final int HOURS24_MODE = 3;

    private static final String TIME_PICKER_SAVED_BUFFER_POINTER =
            "timer_picker_saved_buffer_pointer";
    private static final String TIME_PICKER_SAVED_INPUT = "timer_picker_saved_input";
    private static final String TIME_PICKER_SAVED_AMPM = "timer_picker_saved_ampm";

    public TimePicker(Context context) {
        this(context, null);
    }

    public TimePicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        mInputSize = 4;
        mNoAmPmLabel = context.getResources().getString(R.string.time_picker_ampm_label);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.time_picker_view;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        Resources res = mContext.getResources();
        mAmpm = new DateFormatSymbols().getAmPmStrings();

        if (mIs24HoursMode) {
            mLeft.setText(res.getString(R.string.time_picker_00_label));
            mRight.setText(res.getString(R.string.time_picker_30_label));
        } else {
            mLeft.setText(mAmpm[0]);
            mRight.setText(mAmpm[1]);
        }
        mLeft.setOnClickListener(this);
        mRight.setOnClickListener(this);
        mAmPmLabel = (TextView)findViewById(R.id.ampm_label);
        mAmPmState = AMPM_NOT_SELECTED;
        updateKeypad();
    }


    @Override
    public void onClick(View v) {
        doOnClick(v);
    }

    @Override
    protected void doOnClick(View v) {
        Integer val = (Integer) v.getTag(R.id.numbers_key);
        // A number was pressed
        if (val != null) {
            addClickedNumber(val);
        } else if (v == mDelete) {
            // Pressing delete when AM or PM is selected, clears the AM/PM
            // selection
            if (!mIs24HoursMode && mAmPmState != AMPM_NOT_SELECTED) {
                mAmPmState = AMPM_NOT_SELECTED;
            } else if (mInputPointer >= 0) {
                for (int i = 0; i < mInputPointer; i++) {
                    mInput[i] = mInput[i + 1];
                }
                mInput[mInputPointer] = 0;
                mInputPointer--;
            }
        } else if (v == mLeft) {
            onLeftClicked();
        } else if (v == mRight) {
            onRightClicked();
        }
        updateKeypad();
    }

    @Override
    public boolean onLongClick(View v) {
        if (v == mDelete) {
            mAmPmState = AMPM_NOT_SELECTED;
            reset();
            updateKeypad();
            return true;
        }
        return false;
    }

    private void updateKeypad() {
        // Update state of keypad
        // Set the correct AM/PM state
        showAmPm();
        // Update the time
        updateLeftRightButtons();
        updateTime();
        // enable/disable numeric keys according to the numbers entered already
        updateNumericKeys();
        // enable/disable the "set" key
        enableSetButton();
        // Update the backspace button
        updateDeleteButton();

    }

    // Update the time displayed in the picker:
    // Special cases:
    // 1. show "-" for digits not entered yet.
    // 2. hide the hours digits when it is not relevant
    @Override
    protected void updateTime() {
        // Put "-" in digits that was not entered by passing -1
        // Hide digit by passing -2 (for highest hours digit only);

        int  hours1 = -1;
        int time = getEnteredTime();
        // If the user entered 2 to 9 or 13 to 15 , there is no need for a 4th digit (AM/PM mode)
        // If the user entered 3 to 9 or 24 to 25 , there is no need for a 4th digit (24 hours mode)
        if (mInputPointer > -1) {
            // Test to see if the highest digit is 2 to 9 for AM/PM or 3 to 9 for 24 hours mode
            if (mInputPointer >= 0) {
                int digit = mInput[mInputPointer];
                if ((mIs24HoursMode && digit >= 3 && digit <= 9) ||
                        (!mIs24HoursMode && digit >= 2 && digit <= 9)) {
                    hours1 = -2;
                }
            }
            // Test to see if the 2 highest digits are 13 to 15 for AM/PM or 24 to 25 for 24 hours
            // mode
            if (mInputPointer > 0 && mInputPointer < 3 && hours1 != -2) {
                int digits = mInput[mInputPointer] * 10 + mInput[mInputPointer - 1];
                if ((mIs24HoursMode && digits >= 24 && digits <= 25) ||
                        (!mIs24HoursMode && digits >= 13 && digits <= 15)) {
                    hours1 = -2;
                }
            }
            // If we have a digit show it
            if (mInputPointer == 3) {
                hours1 = mInput[3];
            }
        } else {
            hours1 = -1;
        }
        int hours2 = (mInputPointer < 2) ? -1 :  mInput[2];
        int minutes1 = (mInputPointer < 1) ? -1 :  mInput[1];
        int minutes2 = (mInputPointer < 0) ? -1 :  mInput[0];
        mEnteredTime.setTime(hours1, hours2, minutes1, minutes2, -1);
    }

    private void showAmPm() {
        if (!mIs24HoursMode) {
            switch(mAmPmState) {
                case AMPM_NOT_SELECTED:
                    mAmPmLabel.setText(mNoAmPmLabel);
                    break;
                case AM_SELECTED:
                    mAmPmLabel.setText(mAmpm[0]);
                    break;
                case PM_SELECTED:
                    mAmPmLabel.setText(mAmpm[1]);
                    break;
                default:
                    break;
            }
        } else {
            mAmPmLabel.setVisibility(View.INVISIBLE);
            mAmPmState = HOURS24_MODE;
        }
    }

    private void addClickedNumber(int val) {
        if (mInputPointer < mInputSize - 1) {
            for (int i = mInputPointer; i >= 0; i--) {
                mInput[i + 1] = mInput[i];
            }
            mInputPointer++;
            mInput[0] = val;
        }
    }

    // Clicking on the bottom left button will add "00" to the time
    // In AM/PM mode is will also set the time to AM.
    private void onLeftClicked() {
        int time = getEnteredTime();
        if (!mIs24HoursMode) {
            if (canAddDigits()) {
                addClickedNumber(0);
                addClickedNumber(0);
            }
            mAmPmState = AM_SELECTED;
        } else if (canAddDigits()) {
                addClickedNumber(0);
                addClickedNumber(0);
        }
    }

    // Clicking on the bottom right button will add "00" to the time in AM/PM
    // mode and "30" is 24 hours mode.
    // In AM/PM mode is will also set the time to PM.
    private void onRightClicked() {
        int time = getEnteredTime();
        if (!mIs24HoursMode) {
            if (canAddDigits()) {
                addClickedNumber(0);
                addClickedNumber(0);
            }
            mAmPmState = PM_SELECTED;
        } else {
            if (canAddDigits()) {
                addClickedNumber(3);
                addClickedNumber(0);
            }
        }
    }

    // Checks if the user allowed to click on the left or right button that enters "00" or "30"
    private boolean canAddDigits() {
        int time = getEnteredTime();
        // For AM/PM mode , can add "00" if an hour between 1 and 12 was entered
        if (!mIs24HoursMode) {
            return (time >= 1 && time <= 12);
        }
        // For 24 hours mode , can add "00"/"30" if an hour between 0 and 23 was entered
        return (time >= 0 && time <= 23 && mInputPointer > -1 && mInputPointer < 2);
    }


    // Enable/disable keys in the numeric key pad according to the data entered
    private void updateNumericKeys() {
        int time = getEnteredTime();
        if (mIs24HoursMode) {
            if (mInputPointer >= 3) {
                setKeyRange(-1);
            } else if (time == 0) {
                if (mInputPointer == -1 || mInputPointer == 0 || mInputPointer == 2) {
                    setKeyRange(9);
                } else if (mInputPointer == 1) {
                    setKeyRange(5);
                } else {
                    setKeyRange(-1);
                }
            } else if (time == 1) {
                if (mInputPointer == 0 || mInputPointer == 2) {
                    setKeyRange(9);
                } else  if (mInputPointer == 1) {
                    setKeyRange(5);
                } else {
                    setKeyRange(-1);
                }
            } else if (time == 2) {
                if (mInputPointer == 2|| mInputPointer == 1) {
                    setKeyRange(9);
                } else  if (mInputPointer == 0) {
                    setKeyRange(3);
                } else {
                    setKeyRange(-1);
                }
            } else if (time <= 5) {
                setKeyRange(9);
            } else if (time <= 9) {
                setKeyRange(5);
            } else if (time >= 10 && time <= 15) {
                setKeyRange(9);
            } else if (time >= 16 && time <= 19) {
                setKeyRange(5);
            } else if (time >= 20 && time <= 25) {
                setKeyRange(9);
            } else if (time >= 26 && time <= 29) {
                setKeyRange(-1);
            } else if (time >= 30 && time <= 35) {
                setKeyRange(9);
            } else if (time >= 36 && time <= 39) {
                setKeyRange(-1);
            } else if (time >= 40 && time <= 45) {
                setKeyRange(9);
            } else if (time >= 46 && time <= 49) {
                setKeyRange(-1);
            } else if (time >= 50 && time <= 55) {
                setKeyRange(9);
            } else if (time >= 56 && time <= 59) {
                setKeyRange(-1);
            } else if (time >= 60 && time <= 65) {
                setKeyRange(9);
            } else if (time >= 70 && time <= 75) {
                setKeyRange(9);
            } else if (time >= 80 && time <= 85) {
                setKeyRange(9);
            } else if (time >= 90 && time <= 95) {
                setKeyRange(9);
            } else if (time >= 100 && time <= 105) {
                setKeyRange(9);
            } else if (time >= 106 && time <= 109) {
                setKeyRange(-1);
            } else if (time >= 110 && time <= 115) {
                setKeyRange(9);
            } else if (time >= 116 && time <= 119) {
                setKeyRange(-1);
            } else if (time >= 120 && time <= 125) {
                setKeyRange(9);
            } else if (time >= 126 && time <= 129) {
                setKeyRange(-1);
            } else if (time >= 130 && time <= 135) {
                setKeyRange(9);
            } else if (time >= 136 && time <= 139) {
                setKeyRange(-1);
            } else if (time >= 140 && time <= 145) {
                setKeyRange(9);
            } else if (time >= 146 && time <= 149) {
                setKeyRange(-1);
            } else if (time >= 150 && time <= 155) {
                setKeyRange(9);
            } else if (time >= 156 && time <= 159) {
                setKeyRange(-1);
            } else if (time >= 160 && time <= 165) {
                setKeyRange(9);
            } else if (time >= 166 && time <= 169) {
                setKeyRange(-1);
            } else if (time >= 170 && time <= 175) {
                setKeyRange(9);
            } else if (time >= 176 && time <= 179) {
                setKeyRange(-1);
            } else if (time >= 180 && time <= 185) {
                setKeyRange(9);
            } else if (time >= 186 && time <= 189) {
                setKeyRange(-1);
            } else if (time >= 190 && time <= 195) {
                setKeyRange(9);
            } else if (time >= 196 && time <= 199) {
                setKeyRange(-1);
            } else if (time >= 200 && time <= 205) {
                setKeyRange(9);
            } else if (time >= 206 && time <= 209) {
                setKeyRange(-1);
            } else if (time >= 210 && time <= 215) {
                setKeyRange(9);
            } else if (time >= 216 && time <= 219) {
                setKeyRange(-1);
            } else if (time >= 220 && time <= 225) {
                setKeyRange(9);
            } else if (time >= 226 && time <= 229) {
                setKeyRange(-1);
            } else if (time >= 230 && time <= 235) {
                setKeyRange(9);
            } else if (time >= 236) {
                setKeyRange(-1);
            }
        } else {
            // Selecting AM/PM disabled the keypad
            if (mAmPmState != AMPM_NOT_SELECTED) {
                setKeyRange(-1);
            } else if (time == 0) {
                setKeyRange(9);
                // If 0 was entered as the first digit in AM/PM mode, do not allow a second 0
        //        if (mInputPointer == 0) {
                    mNumbers[0].setEnabled(false);
          //      }
            } else if (time <= 9) {
                setKeyRange(5);
            } else if (time <= 95) {
                setKeyRange(9);
            } else if (time >= 100 && time <= 105) {
                setKeyRange(9);
            } else if (time >= 106 && time <= 109) {
                setKeyRange(-1);
            } else if (time >= 110 && time <= 115) {
                setKeyRange(9);
            } else if (time >= 116 && time <= 119) {
                setKeyRange(-1);
            } else if (time >= 120 && time <= 125) {
                setKeyRange(9);
            } else if (time >= 126) {
                setKeyRange(-1);
            }
        }
    }

    // Returns the time already entered in decimal representation. if time is H1 H2 : M1 M2
    // the value retured is H1*1000+H2*100+M1*10+M2
    private int getEnteredTime() {
        return  mInput[3] * 1000 + mInput[2] * 100 + mInput[1] * 10 + mInput[0];
    }

    // enables a range of numeric keys from zero to maxKey. The rest of the keys will be disabled
    private void setKeyRange(int maxKey) {
        for (int i = 0; i < mNumbers.length; i++) {
            mNumbers[i].setEnabled(i <= maxKey);
        }
    }

    private void updateLeftRightButtons() {
        int time = getEnteredTime();
        if (mIs24HoursMode) {
            boolean enable = canAddDigits();
            mLeft.setEnabled(enable);
            mRight.setEnabled(enable);
        } else {
            // You can use the AM/PM if time entered is 0 to 12 or it is 3 digits or more
            if ((time > 12 && time < 100) || time == 0 || mAmPmState != AMPM_NOT_SELECTED) {
                mLeft.setEnabled(false);
                mRight.setEnabled(false);
            } else {
                mLeft.setEnabled(true);
                mRight.setEnabled(true);
            }
        }
    }

    // Enable/disable the set key
    private void enableSetButton() {
        if (mSetButton == null) {
            return;
        }

        // Nothing entered - disable
        if (mInputPointer == -1) {
            mSetButton.setEnabled(false);
            return;
        }
        // If the user entered 3 digits or more but not 060 to 095
        // it is a legal time and the set key should be enabled.
        if (mIs24HoursMode) {
            int time = getEnteredTime();
            mSetButton.setEnabled(mInputPointer >= 2 && (time < 60 || time > 95));
        } else {
            // If AM/PM mode , enable the set button if AM/PM was selected
            mSetButton.setEnabled(mAmPmState != AMPM_NOT_SELECTED);
        }
    }

    public void setSetButton(Button b) {
        mSetButton = b;
        enableSetButton();
    }

    public int getHours() {
        int hours = mInput[3] * 10 + mInput[2];
        if (hours == 12) {
            switch (mAmPmState) {
                case PM_SELECTED:
                    return 12;
                case AM_SELECTED:
                    return 0;
                case HOURS24_MODE:
                    return hours;
                default:
                    break;
            }
        }
        return hours + (mAmPmState == PM_SELECTED ? 12 : 0);
    }
    public int getMinutes() {
        return mInput[1] * 10 + mInput[0];
    }

    @Override
    public Parcelable onSaveInstanceState () {
        final Parcelable parcel = super.onSaveInstanceState();
        final SavedState state = new SavedState(parcel);
        state.mInput = mInput;
        state.mAmPmState = mAmPmState;
        state.mInputPointer = mInputPointer;
        return state;
    }

    @Override
    protected void onRestoreInstanceState (Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }

        final SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());

        mInputPointer = savedState.mInputPointer;
        mInput = savedState.mInput;
        if (mInput == null) {
            mInput = new int[mInputSize];
            mInputPointer = -1;
        }
        mAmPmState = savedState.mAmPmState;
        updateKeypad();
    }

    private static class SavedState extends BaseSavedState {
        int mInputPointer;
        int[] mInput;
        int mAmPmState;

        public SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            mInputPointer = in.readInt();
            in.readIntArray(mInput);
            mAmPmState = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(mInputPointer);
            dest.writeIntArray(mInput);
            dest.writeInt(mAmPmState);
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}
