/*
 * 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.content.Context;
import android.util.Log;
import android.view.ContextThemeWrapper;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Phone;

/**
 * Helper class to manage the options menu for the InCallScreen.
 *
 * This class is the "Model" (in M-V-C nomenclature) for the in-call menu;
 * it knows about all possible menu items, and contains logic to determine
 * the current state and enabledness of each item based on the state of
 * the Phone.
 *
 * The corresponding View classes are InCallMenuView, which is used purely
 * to lay out and draw the menu, and InCallMenuItemView, which is the View
 * for a single item.
 */
class InCallMenu {
    private static final String LOG_TAG = "PHONE/InCallMenu";
    private static final boolean DBG = false;

    /**
     * Reference to the InCallScreen activity that owns us.  This will be
     * null if we haven't been initialized yet *or* after the InCallScreen
     * activity has been destroyed.
     */
    private InCallScreen mInCallScreen;

    /**
     * Our corresponding View class.
     */
    private InCallMenuView mInCallMenuView;

    /**
     * All possible menu items (see initMenu().)
     */
    InCallMenuItemView mManageConference;
    InCallMenuItemView mShowDialpad;
    InCallMenuItemView mEndCall;
    InCallMenuItemView mAddCall;
    InCallMenuItemView mSwapCalls;
    InCallMenuItemView mMergeCalls;
    InCallMenuItemView mBluetooth;
    InCallMenuItemView mSpeaker;
    InCallMenuItemView mMute;
    InCallMenuItemView mHold;
    InCallMenuItemView mAnswerAndHold;
    InCallMenuItemView mAnswerAndEnd;
    InCallMenuItemView mAnswer;
    InCallMenuItemView mIgnore;

    InCallMenu(InCallScreen inCallScreen) {
        if (DBG) log("InCallMenu constructor...");
        mInCallScreen = inCallScreen;
    }

    /**
     * Null out our reference to the InCallScreen activity.
     * This indicates that the InCallScreen activity has been destroyed.
     */
    void clearInCallScreenReference() {
        mInCallScreen = null;
        if (mInCallMenuView != null) mInCallMenuView.clearInCallScreenReference();
    }

    /* package */ InCallMenuView getView() {
        return mInCallMenuView;
    }

    /**
     * Initializes the in-call menu by creating a new InCallMenuView,
     * creating all possible menu items, and loading them into the
     * InCallMenuView.
     *
     * The only initialization of the individual items we do here is
     * one-time stuff, like setting the ID and click listener, or calling
     * setIndicatorVisible() for buttons that have a green LED, or calling
     * setText() for buttons whose text never changes.  The actual
     * *current* state and enabledness of each item is set in
     * updateItems().
     */
    /* package */ void initMenu() {
        if (DBG) log("initMenu()...");

        // Explicitly use the "icon menu" theme for the Views we create.
        Context wrappedContext = new ContextThemeWrapper(
                mInCallScreen,
                com.android.internal.R.style.Theme_IconMenu);

        mInCallMenuView = new InCallMenuView(wrappedContext, mInCallScreen);

        //
        // Create all possible InCallMenuView objects.
        //

        mManageConference = new InCallMenuItemView(wrappedContext);
        mManageConference.setId(R.id.menuManageConference);
        mManageConference.setOnClickListener(mInCallScreen);
        mManageConference.setText(R.string.menu_manageConference);
        mManageConference.setIconResource(com.android.internal.R.drawable.ic_menu_allfriends);

        mShowDialpad = new InCallMenuItemView(wrappedContext);
        mShowDialpad.setId(R.id.menuShowDialpad);
        mShowDialpad.setOnClickListener(mInCallScreen);
        mShowDialpad.setText(R.string.menu_showDialpad); // or "Hide dialpad" if it's open
        mShowDialpad.setIconResource(R.drawable.ic_menu_dial_pad);

        mEndCall = new InCallMenuItemView(wrappedContext);
        mEndCall.setId(R.id.menuEndCall);
        mEndCall.setOnClickListener(mInCallScreen);
        mEndCall.setText(R.string.menu_endCall);
        mEndCall.setIconResource(R.drawable.ic_menu_end_call);

        mAddCall = new InCallMenuItemView(wrappedContext);
        mAddCall.setId(R.id.menuAddCall);
        mAddCall.setOnClickListener(mInCallScreen);
        mAddCall.setText(R.string.menu_addCall);
        mAddCall.setIconResource(android.R.drawable.ic_menu_add);

        mSwapCalls = new InCallMenuItemView(wrappedContext);
        mSwapCalls.setId(R.id.menuSwapCalls);
        mSwapCalls.setOnClickListener(mInCallScreen);
        mSwapCalls.setText(R.string.menu_swapCalls);
        mSwapCalls.setIconResource(R.drawable.ic_menu_swap_calls);

        mMergeCalls = new InCallMenuItemView(wrappedContext);
        mMergeCalls.setId(R.id.menuMergeCalls);
        mMergeCalls.setOnClickListener(mInCallScreen);
        mMergeCalls.setText(R.string.menu_mergeCalls);
        mMergeCalls.setIconResource(R.drawable.ic_menu_merge_calls);

        // TODO: Icons for menu items we don't have yet:
        //   R.drawable.ic_menu_answer_call
        //   R.drawable.ic_menu_silence_ringer

        mBluetooth = new InCallMenuItemView(wrappedContext);
        mBluetooth.setId(R.id.menuBluetooth);
        mBluetooth.setOnClickListener(mInCallScreen);
        mBluetooth.setText(R.string.menu_bluetooth);
        mBluetooth.setIndicatorVisible(true);

        mSpeaker = new InCallMenuItemView(wrappedContext);
        mSpeaker.setId(R.id.menuSpeaker);
        mSpeaker.setOnClickListener(mInCallScreen);
        mSpeaker.setText(R.string.menu_speaker);
        mSpeaker.setIndicatorVisible(true);

        mMute = new InCallMenuItemView(wrappedContext);
        mMute.setId(R.id.menuMute);
        mMute.setOnClickListener(mInCallScreen);
        mMute.setText(R.string.menu_mute);
        mMute.setIndicatorVisible(true);

        mHold = new InCallMenuItemView(wrappedContext);
        mHold.setId(R.id.menuHold);
        mHold.setOnClickListener(mInCallScreen);
        mHold.setText(R.string.menu_hold);
        mHold.setIndicatorVisible(true);

        mAnswerAndHold = new InCallMenuItemView(wrappedContext);
        mAnswerAndHold.setId(R.id.menuAnswerAndHold);
        mAnswerAndHold.setOnClickListener(mInCallScreen);
        mAnswerAndHold.setText(R.string.menu_answerAndHold);

        mAnswerAndEnd = new InCallMenuItemView(wrappedContext);
        mAnswerAndEnd.setId(R.id.menuAnswerAndEnd);
        mAnswerAndEnd.setOnClickListener(mInCallScreen);
        mAnswerAndEnd.setText(R.string.menu_answerAndEnd);

        mAnswer = new InCallMenuItemView(wrappedContext);
        mAnswer.setId(R.id.menuAnswer);
        mAnswer.setOnClickListener(mInCallScreen);
        mAnswer.setText(R.string.menu_answer);

        mIgnore = new InCallMenuItemView(wrappedContext);
        mIgnore.setId(R.id.menuIgnore);
        mIgnore.setOnClickListener(mInCallScreen);
        mIgnore.setText(R.string.menu_ignore);

        //
        // Load all the items into the correct "slots" in the InCallMenuView.
        //
        // Row 0 is the topmost row onscreen, item 0 is the leftmost item in a row.
        //
        // Individual items may be disabled or hidden, but never move between
        // rows or change their order within a row.
        //
        // TODO: these items and their layout ought be specifiable
        // entirely in XML (just like we currently do with res/menu/*.xml
        // files.)
        //

        // Row 0:
        // This usually has "Show/Hide dialpad", but that gets replaced by
        // "Manage conference" if a conference call is active.
        PhoneApp app = PhoneApp.getInstance();
        // As managing conference is only valid for GSM and not for CDMA
        int phoneType = app.phone.getPhoneType();
        if (phoneType == Phone.PHONE_TYPE_GSM) {
            mInCallMenuView.addItemView(mManageConference, 0);
        }
        mInCallMenuView.addItemView(mShowDialpad, 0);

        // Row 1:
        mInCallMenuView.addItemView(mSwapCalls, 1);
        mInCallMenuView.addItemView(mMergeCalls, 1);
        mInCallMenuView.addItemView(mAddCall, 1);
        mInCallMenuView.addItemView(mEndCall, 1);

        // Row 2:
        // In this row we see *either*  bluetooth/speaker/mute/hold
        // *or* answerAndHold/answerAndEnd, but never all 6 together.
        // For CDMA only Answer or Ignore option is valid for a Call Waiting scenario
        if (phoneType == Phone.PHONE_TYPE_CDMA) {
            mInCallMenuView.addItemView(mAnswer, 2);
            mInCallMenuView.addItemView(mIgnore, 2);
        } else if (phoneType == Phone.PHONE_TYPE_GSM) {
            mInCallMenuView.addItemView(mHold, 2);
            mInCallMenuView.addItemView(mAnswerAndHold, 2);
            mInCallMenuView.addItemView(mAnswerAndEnd, 2);
        } else {
            throw new IllegalStateException("Unexpected phone type: " + phoneType);
        }
        mInCallMenuView.addItemView(mMute, 2);
        mInCallMenuView.addItemView(mSpeaker, 2);
        mInCallMenuView.addItemView(mBluetooth, 2);

        mInCallMenuView.dumpState();
    }

    /**
     * Updates the enabledness and visibility of all items in the
     * InCallMenuView based on the current state of the Phone.
     *
     * This is called every time we need to display the menu, right before
     * it becomes visible.
     *
     * @return true if we successfully updated the items and it's OK
     *         to go ahead and show the menu, or false if
     *         we shouldn't show the menu at all.
     */
    /* package */ boolean updateItems(Phone phone) {
        if (DBG) log("updateItems()...");
        // if (DBG) PhoneUtils.dumpCallState(phone);

        // If the phone is totally idle (like in the "call ended" state)
        // there's no menu at all.
        if (phone.getState() == Phone.State.IDLE) {
            if (DBG) log("- Phone is idle!  Don't show the menu...");
            return false;
        }

        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
        final Call.State fgCallState = phone.getForegroundCall().getState();
        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();

        // For OTA call, only show dialpad, endcall, speaker, and mute menu items
        if (hasActiveCall && (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) &&
                (PhoneApp.getInstance().isOtaCallInActiveState())) {
            mAnswerAndHold.setVisible(false);
            mAnswerAndHold.setEnabled(false);
            mAnswerAndEnd.setVisible(false);
            mAnswerAndEnd.setEnabled(false);

            mManageConference.setVisible(false);
            mAddCall.setEnabled(false);
            mSwapCalls.setEnabled(false);
            mMergeCalls.setEnabled(false);
            mHold.setEnabled(false);
            mBluetooth.setEnabled(false);
            mMute.setEnabled(false);
            mAnswer.setVisible(false);
            mIgnore.setVisible(false);

            boolean inConferenceCall =
                    PhoneUtils.isConferenceCall(phone.getForegroundCall());
            boolean showShowDialpad = !inConferenceCall;
            boolean enableShowDialpad = showShowDialpad && mInCallScreen.okToShowDialpad();
            mShowDialpad.setVisible(showShowDialpad);
            mShowDialpad.setEnabled(enableShowDialpad);
            boolean isDtmfDialerOpened = mInCallScreen.isDialerOpened();
            mShowDialpad.setText(isDtmfDialerOpened
                                 ? R.string.menu_hideDialpad
                                 : R.string.menu_showDialpad);

            mEndCall.setVisible(true);
            mEndCall.setEnabled(true);

            mSpeaker.setVisible(true);
            mSpeaker.setEnabled(true);
            boolean speakerOn = PhoneUtils.isSpeakerOn(mInCallScreen.getApplicationContext());
            mSpeaker.setIndicatorState(speakerOn);

            mInCallMenuView.updateVisibility();
            return true;
        }

        // Special cases when an incoming call is ringing.
        if (hasRingingCall) {
            // In the "call waiting" state, show ONLY the "answer & end"
            // and "answer & hold" buttons, and nothing else.
            // TODO: be sure to test this for "only one line in use and it's
            // active" AND for "only one line in use and it's on hold".
            if (hasActiveCall && !hasHoldingCall) {
                int phoneType = phone.getPhoneType();
                // For CDMA only make "Answer" and "Ignore" visible
                if (phoneType == Phone.PHONE_TYPE_CDMA) {
                    mAnswer.setVisible(true);
                    mAnswer.setEnabled(true);
                    mIgnore.setVisible(true);
                    mIgnore.setEnabled(true);

                    // Explicitly remove GSM menu items
                    mAnswerAndHold.setVisible(false);
                    mAnswerAndEnd.setVisible(false);
                } else if (phoneType == Phone.PHONE_TYPE_GSM) {
                    mAnswerAndHold.setVisible(true);
                    mAnswerAndHold.setEnabled(true);
                    mAnswerAndEnd.setVisible(true);
                    mAnswerAndEnd.setEnabled(true);

                    // Explicitly remove CDMA menu items
                    mAnswer.setVisible(false);
                    mIgnore.setVisible(false);

                    mManageConference.setVisible(false);
                } else {
                    throw new IllegalStateException("Unexpected phone type: " + phoneType);
                }

                mShowDialpad.setVisible(false);
                mEndCall.setVisible(false);
                mAddCall.setVisible(false);
                mSwapCalls.setVisible(false);
                mMergeCalls.setVisible(false);
                mBluetooth.setVisible(false);
                mSpeaker.setVisible(false);
                mMute.setVisible(false);
                mHold.setVisible(false);

                // Done updating the individual items.
                // The last step is to tell the InCallMenuView to update itself
                // based on any visibility changes that just happened.
                mInCallMenuView.updateVisibility();

                return true;
            } else {
                // If there's an incoming ringing call but there aren't
                // any "special actions" to take, don't show a menu at all.
                return false;
            }
        }

        // TODO: double-check if any items here need to be disabled based on:
        //   boolean keyguardRestricted = mInCallScreen.isPhoneStateRestricted();

        // The InCallControlState object tells us the enabledness and/or
        // state of the various menu items:
        InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();

        // Manage conference: visible only if the foreground call is a
        // conference call.  Enabled unless the "Manage conference" UI is
        // already up.
        mManageConference.setVisible(inCallControlState.manageConferenceVisible);
        mManageConference.setEnabled(inCallControlState.manageConferenceEnabled);

        // "Show/Hide dialpad":
        // - Visible: only in portrait mode, but NOT when "Manage
        //   conference" is available (since that's shown instead.)
        // - Enabled: Only when it's OK to use the dialpad in the first
        //   place (i.e. in the same states where the SlidingDrawer handle
        //   is visible.)
        // - Text label: "Show" or "Hide", depending on the current state
        //   of the sliding drawer.
        // (Note this logic is totally specific to the in-call menu, so
        // this state doesn't come from the inCallControlState object.)
        boolean showShowDialpad = !inCallControlState.manageConferenceVisible;
        boolean enableShowDialpad = showShowDialpad && mInCallScreen.okToShowDialpad();
        mShowDialpad.setVisible(showShowDialpad);
        mShowDialpad.setEnabled(enableShowDialpad);
        mShowDialpad.setText(inCallControlState.dialpadVisible
                             ? R.string.menu_hideDialpad
                             : R.string.menu_showDialpad);

        // "End call": this button has no state and is always visible.
        // It's also always enabled.  (Actually it *would* need to be
        // disabled if the phone was totally idle, but the entire in-call
        // menu is already disabled in that case (see above.))
        mEndCall.setVisible(true);
        mEndCall.setEnabled(true);

        // "Add call"
        mAddCall.setVisible(true);
        mAddCall.setEnabled(inCallControlState.canAddCall);

        // Swap / merge calls
        mSwapCalls.setVisible(true);
        mSwapCalls.setEnabled(inCallControlState.canSwap);
        mMergeCalls.setVisible(true);
        mMergeCalls.setEnabled(inCallControlState.canMerge);

        // "Bluetooth": always visible, only enabled if BT is available.
        mBluetooth.setVisible(true);
        mBluetooth.setEnabled(inCallControlState.bluetoothEnabled);
        mBluetooth.setIndicatorState(inCallControlState.bluetoothIndicatorOn);

        // "Speaker": always visible.  Disabled if a wired headset is
        // plugged in, otherwise enabled (and indicates the current
        // speaker state.)
        mSpeaker.setVisible(true);
        mSpeaker.setEnabled(inCallControlState.speakerEnabled);
        mSpeaker.setIndicatorState(inCallControlState.speakerOn);

        // "Mute": only enabled when the foreground call is ACTIVE.
        // (It's meaningless while on hold, or while DIALING/ALERTING.)
        // Also disabled (on CDMA devices) during emergency calls.
        mMute.setVisible(true);
        mMute.setEnabled(inCallControlState.canMute);
        mMute.setIndicatorState(inCallControlState.muteIndicatorOn);

        // "Hold"
        mHold.setVisible(inCallControlState.supportsHold);
        mHold.setIndicatorState(inCallControlState.onHold);
        mHold.setEnabled(inCallControlState.canHold);

        // "Answer" and "Ignore" are used only when there's an incoming
        // ringing call (see above).  (And for now they're only used in
        // CDMA, for the call waiting case.)
        mAnswer.setVisible(false);
        mAnswer.setEnabled(false);
        mIgnore.setVisible(false);
        mIgnore.setEnabled(false);

        // "Answer & end" and "Answer & hold" are only useful
        // when there's an incoming ringing call (see above.)
        mAnswerAndHold.setVisible(false);
        mAnswerAndHold.setEnabled(false);
        mAnswerAndEnd.setVisible(false);
        mAnswerAndEnd.setEnabled(false);

        // Done updating the individual items.
        // The last step is to tell the InCallMenuView to update itself
        // based on any visibility changes that just happened.
        mInCallMenuView.updateVisibility();

        return true;
    }


    private void log(String msg) {
        Log.d(LOG_TAG, msg);
    }
}
