/*
 * 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.phone2;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.preference.EditTextPreference;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.DialerKeyListener;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

public class EditPhoneNumberPreference extends EditTextPreference {

    //allowed modes for this preference.
    /** simple confirmation (OK / CANCEL) */
    private static final int CM_CONFIRM = 0;
    /** toggle [(ENABLE / CANCEL) or (DISABLE / CANCEL)], use isToggled() to see requested state.*/
    private static final int CM_ACTIVATION = 1;

    private int mConfirmationMode;

    //String constants used in storing the value of the preference
    // The preference is backed by a string that holds the encoded value, which reads:
    //  <VALUE_ON | VALUE_OFF><VALUE_SEPARATOR><mPhoneNumber>
    // for example, an enabled preference with a number of 6502345678 would read:
    //  "1:6502345678"
    private static final String VALUE_SEPARATOR = ":";
    private static final String VALUE_OFF = "0";
    private static final String VALUE_ON = "1";

    //UI layout
    private ImageButton mContactPickButton;

    //Listeners
    /** Called when focus is changed between fields */
    private View.OnFocusChangeListener mDialogFocusChangeListener;
    /** Called when the Dialog is closed. */
    private OnDialogClosedListener mDialogOnClosedListener;
    /**
     * Used to indicate that we are going to request for a
     * default number. for the dialog.
     */
    private GetDefaultNumberListener mGetDefaultNumberListener;

    //Activity values
    private Activity mParentActivity;
    private Intent mContactListIntent;
    /** Arbitrary activity-assigned preference id value */
    private int mPrefId;

    //similar to toggle preference
    private CharSequence mEnableText;
    private CharSequence mDisableText;
    private CharSequence mChangeNumberText;
    private CharSequence mSummaryOn;
    private CharSequence mSummaryOff;

    // button that was clicked on dialog close.
    private int mButtonClicked;

    //relevant (parsed) value of the mText
    private String mPhoneNumber;
    private boolean mChecked;


    /**
     * Interface for the dialog closed listener, related to
     * DialogPreference.onDialogClosed(), except we also pass in a buttonClicked
     * value indicating which of the three possible buttons were pressed.
     */
    interface OnDialogClosedListener {
        void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked);
    }

    /**
     * Interface for the default number setting listener.  Handles requests for
     * the default display number for the dialog.
     */
    interface GetDefaultNumberListener {
        /**
         * Notify that we are looking for a default display value.
         * @return null if there is no contribution from this interface,
         *  indicating that the orignal value of mPhoneNumber should be
         *  displayed unchanged.
         */
        String onGetDefaultNumber(EditPhoneNumberPreference preference);
    }

    /*
     * Constructors
     */
    public EditPhoneNumberPreference(Context context, AttributeSet attrs) {
        super(context, attrs);

        setDialogLayoutResource(R.layout.pref_dialog_editphonenumber);

        //create intent to bring up contact list
        mContactListIntent = new Intent(Intent.ACTION_GET_CONTENT);
        mContactListIntent.setType(Phone.CONTENT_ITEM_TYPE);

        //get the edit phone number default settings
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.EditPhoneNumberPreference, 0, R.style.EditPhoneNumberPreference);
        mEnableText = a.getString(R.styleable.EditPhoneNumberPreference_enableButtonText);
        mDisableText = a.getString(R.styleable.EditPhoneNumberPreference_disableButtonText);
        mChangeNumberText = a.getString(R.styleable.EditPhoneNumberPreference_changeNumButtonText);
        mConfirmationMode = a.getInt(R.styleable.EditPhoneNumberPreference_confirmMode, 0);
        a.recycle();

        //get the summary settings, use CheckBoxPreference as the standard.
        a = context.obtainStyledAttributes(attrs, android.R.styleable.CheckBoxPreference, 0, 0);
        mSummaryOn = a.getString(android.R.styleable.CheckBoxPreference_summaryOn);
        mSummaryOff = a.getString(android.R.styleable.CheckBoxPreference_summaryOff);
        a.recycle();
    }

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


    /*
     * Methods called on UI bindings
     */
    @Override
    //called when we're binding the view to the preference.
    protected void onBindView(View view) {
        super.onBindView(view);

        // Sync the summary view
        TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
        if (summaryView != null) {
            CharSequence sum;
            int vis;

            //set summary depending upon mode
            if (mConfirmationMode == CM_ACTIVATION) {
                if (mChecked) {
                    sum = (mSummaryOn == null) ? getSummary() : mSummaryOn;
                } else {
                    sum = (mSummaryOff == null) ? getSummary() : mSummaryOff;
                }
            } else {
                sum = getSummary();
            }

            if (sum != null) {
                summaryView.setText(sum);
                vis = View.VISIBLE;
            } else {
                vis = View.GONE;
            }

            if (vis != summaryView.getVisibility()) {
                summaryView.setVisibility(vis);
            }
        }
    }

    //called when we're binding the dialog to the preference's view.
    @Override
    protected void onBindDialogView(View view) {
        // default the button clicked to be the cancel button.
        mButtonClicked = DialogInterface.BUTTON2;

        super.onBindDialogView(view);

        //get the edittext component within the number field
        EditText editText = getEditText();
        //get the contact pick button within the number field
        mContactPickButton = (ImageButton) view.findViewById(R.id.select_contact);

        //setup number entry
        if (editText != null) {
            // see if there is a means to get a default number,
            // and set it accordingly.
            if (mGetDefaultNumberListener != null) {
                String defaultNumber = mGetDefaultNumberListener.onGetDefaultNumber(this);
                if (defaultNumber != null) {
                    mPhoneNumber = defaultNumber;
                }
            }
            editText.setText(mPhoneNumber);
            editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
            editText.setKeyListener(DialerKeyListener.getInstance());
            editText.setOnFocusChangeListener(mDialogFocusChangeListener);
        }

        //set contact picker
        if (mContactPickButton != null) {
            mContactPickButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    if (mParentActivity != null) {
                        mParentActivity.startActivityForResult(mContactListIntent, mPrefId);
                    }
                }
            });
        }
    }

    /**
     * Overriding EditTextPreference's onAddEditTextToDialogView.
     *
     * This method attaches the EditText to the container specific to this
     * preference's dialog layout.
     */
    @Override
    protected void onAddEditTextToDialogView(View dialogView, EditText editText) {

        // look for the container object
        ViewGroup container = (ViewGroup) dialogView
                .findViewById(R.id.edit_container);

        // add the edittext to the container.
        if (container != null) {
            container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
    }

    //control the appearance of the dialog depending upon the mode.
    @Override
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
        // modified so that we just worry about the buttons being
        // displayed, since there is no need to hide the edittext
        // field anymore.
        if (mConfirmationMode == CM_ACTIVATION) {
            if (mChecked) {
                builder.setPositiveButton(mChangeNumberText, this);
                builder.setNeutralButton(mDisableText, this);
            } else {
                builder.setPositiveButton(null, null);
                builder.setNeutralButton(mEnableText, this);
            }
        }
        // set the call icon on the title.
        builder.setIcon(R.drawable.ic_dialog_call);
    }


    /*
     * Listeners and other state setting methods
     */
    //set the on focus change listener to be assigned to the Dialog's edittext field.
    public void setDialogOnFocusChangeListener(View.OnFocusChangeListener l) {
        mDialogFocusChangeListener = l;
    }

    //set the listener to be called wht the dialog is closed.
    public void setDialogOnClosedListener(OnDialogClosedListener l) {
        mDialogOnClosedListener = l;
    }

    //set the link back to the parent activity, so that we may run the contact picker.
    public void setParentActivity(Activity parent, int identifier) {
        mParentActivity = parent;
        mPrefId = identifier;
        mGetDefaultNumberListener = null;
    }

    //set the link back to the parent activity, so that we may run the contact picker.
    //also set the default number listener.
    public void setParentActivity(Activity parent, int identifier, GetDefaultNumberListener l) {
        mParentActivity = parent;
        mPrefId = identifier;
        mGetDefaultNumberListener = l;
    }

    /*
     * Notification handlers
     */
    //Notify the preference that the pick activity is complete.
    public void onPickActivityResult(String pickedValue) {
        EditText editText = getEditText();
        if (editText != null) {
            editText.setText(pickedValue);
        }
    }

    //called when the dialog is clicked.
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // The neutral button (button3) is always the toggle.
        if ((mConfirmationMode == CM_ACTIVATION) && (which == DialogInterface.BUTTON3)) {
            //flip the toggle if we are in the correct mode.
            setToggled(!isToggled());
        }
        // record the button that was clicked.
        mButtonClicked = which;
        super.onClick(dialog, which);
    }

    @Override
    //When the dialog is closed, perform the relevant actions, including setting
    // phone numbers and calling the close action listener.
    protected void onDialogClosed(boolean positiveResult) {
        // A positive result is technically either button1 or button3.
        if ((mButtonClicked == DialogInterface.BUTTON1) ||
                (mButtonClicked == DialogInterface.BUTTON3)){
            setPhoneNumber(getEditText().getText().toString());
            super.onDialogClosed(positiveResult);
            setText(getStringValue());
        } else {
            super.onDialogClosed(positiveResult);
        }

        // send the clicked button over to the listener.
        if (mDialogOnClosedListener != null) {
            mDialogOnClosedListener.onDialogClosed(this, mButtonClicked);
        }
    }


    /*
     * Toggle handling code.
     */
    //return the toggle value.
    public boolean isToggled() {
        return mChecked;
    }

    //set the toggle value.
    // return the current preference to allow for chaining preferences.
    public EditPhoneNumberPreference setToggled(boolean checked) {
        mChecked = checked;
        setText(getStringValue());
        notifyChanged();

        return this;
    }


    /**
     * Phone number handling code
     */
    public String getPhoneNumber() {
        // return the phone number, after it has been stripped of all
        // irrelevant text.
        return PhoneNumberUtils.stripSeparators(mPhoneNumber);
    }

    /** The phone number including any formatting characters */
    protected String getRawPhoneNumber() {
        return mPhoneNumber;
    }

    //set the phone number value.
    // return the current preference to allow for chaining preferences.
    public EditPhoneNumberPreference setPhoneNumber(String number) {
        mPhoneNumber = number;
        setText(getStringValue());
        notifyChanged();

        return this;
    }


    /*
     * Other code relevant to preference framework
     */
    //when setting default / initial values, make sure we're setting things correctly.
    @Override
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        setValueFromString(restoreValue ? getPersistedString(getStringValue())
                : (String) defaultValue);
    }

    /**
     * Decides how to disable dependents.
     */
    @Override
    public boolean shouldDisableDependents() {
        // There is really only one case we care about, but for consistency
        // we fill out the dependency tree for all of the cases.  If this
        // is in activation mode (CF), we look for the encoded toggle value
        // in the string.  If this in confirm mode (VM), then we just
        // examine the number field.
        // Note: The toggle value is stored in the string in an encoded
        // manner (refer to setValueFromString and getStringValue below).
        boolean shouldDisable = false;
        if ((mConfirmationMode == CM_ACTIVATION) && (mEncodedText != null)) {
            String[] inValues = mEncodedText.split(":", 2);
            shouldDisable = inValues[0].equals(VALUE_ON);
        } else {
            shouldDisable = (TextUtils.isEmpty(mPhoneNumber) && (mConfirmationMode == CM_CONFIRM));
        }
        return shouldDisable;
    }

    /**
     * Override persistString so that we can get a hold of the EditTextPreference's
     * text field.
     */
    private String mEncodedText = null;
    @Override
    protected boolean persistString(String value) {
        mEncodedText = value;
        return super.persistString(value);
    }


    /*
     * Summary On handling code
     */
    //set the Summary for the on state (relevant only in CM_ACTIVATION mode)
    public EditPhoneNumberPreference setSummaryOn(CharSequence summary) {
        mSummaryOn = summary;
        if (isToggled()) {
            notifyChanged();
        }
        return this;
    }

    //set the Summary for the on state, given a string resource id
    // (relevant only in CM_ACTIVATION mode)
    public EditPhoneNumberPreference setSummaryOn(int summaryResId) {
        return setSummaryOn(getContext().getString(summaryResId));
    }

    //get the summary string for the on state
    public CharSequence getSummaryOn() {
        return mSummaryOn;
    }


    /*
     * Summary Off handling code
     */
    //set the Summary for the off state (relevant only in CM_ACTIVATION mode)
    public EditPhoneNumberPreference setSummaryOff(CharSequence summary) {
        mSummaryOff = summary;
        if (!isToggled()) {
            notifyChanged();
        }
        return this;
    }

    //set the Summary for the off state, given a string resource id
    // (relevant only in CM_ACTIVATION mode)
    public EditPhoneNumberPreference setSummaryOff(int summaryResId) {
        return setSummaryOff(getContext().getString(summaryResId));
    }

    //get the summary string for the off state
    public CharSequence getSummaryOff() {
        return mSummaryOff;
    }


    /*
     * Methods to get and set from encoded strings.
     */
    //set the values given an encoded string.
    protected void setValueFromString(String value) {
        String[] inValues = value.split(":", 2);
        setToggled(inValues[0].equals(VALUE_ON));
        setPhoneNumber(inValues[1]);
    }

    //retrieve the state of this preference in the form of an encoded string
    protected String getStringValue() {
        return ((isToggled() ? VALUE_ON : VALUE_OFF) + VALUE_SEPARATOR + getPhoneNumber());
    }

    /**
     * Externally visible method to bring up the dialog.
     *
     * Generally used when we are navigating the user to this preference.
     */
    public void showPhoneNumberDialog() {
        showDialog(null);
    }
}
