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

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.BidiFormatter;
import android.text.TextDirectionHeuristics;
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.
     */
    public 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.
     */
    public 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.BUTTON_NEGATIVE;

        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(BidiFormatter.getInstance().unicodeWrap(
                    mPhoneNumber, TextDirectionHeuristics.LTR));
            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.mipmap.ic_launcher_phone);
    }


    /*
     * 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.BUTTON_NEUTRAL)) {
            //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.BUTTON_POSITIVE) ||
                (mButtonClicked == DialogInterface.BUTTON_NEUTRAL)){
            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);
    }
}
