package com.gs.apidemo;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.gs.phone.api.audio.AudioRouteApi;
import com.gs.phone.api.call.BaseCallApi;
import com.gs.phone.api.line.BaseLineApi;
import com.gs.phone.api.setting.CallSettingApi;
import com.gs.phone.context.PhoneContext;
import com.gs.phone.entity.BaseLine;
import com.gs.phone.listener.CallStatusListener;

import java.util.ArrayList;
import java.util.List;

public class TalkingActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "TalkingActivity";
    private TextView mNumberTv, mNameTv, mStatusTv;
    private Button mSelectLineBtn, mAcceptBtn, mEndBtn, mTransBtn, mTransferNowBtn, mSplitBtn, mCancelBtn, mUnHoldBtn;
    private int mPrevStatus = -1;
    private BaseLine mSelectedLine, mTransferTargetLine;
    private MediaPlayer mMediaPlayer;
    private boolean isInAttendTransfer = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_talking);
        mNumberTv = (TextView) findViewById(R.id.tv_number);
        mNameTv = (TextView) findViewById(R.id.tv_name);
        mStatusTv = (TextView) findViewById(R.id.tv_line_status);
        mAcceptBtn = (Button) findViewById(R.id.btn_accept);
        mAcceptBtn.setOnClickListener(this);
        mEndBtn = (Button) findViewById(R.id.btn_end);
        mEndBtn.setOnClickListener(this);
        mTransBtn = (Button) findViewById(R.id.btn_transfer);
        mTransBtn.setOnClickListener(this);
        mTransferNowBtn = (Button) findViewById(R.id.btn_transfer_now);
        mTransferNowBtn.setOnClickListener(this);
        mSplitBtn = (Button) findViewById(R.id.btn_split);
        mSplitBtn.setOnClickListener(this);
        mCancelBtn = (Button) findViewById(R.id.btn_cancel);
        mCancelBtn.setOnClickListener(this);
        mSelectLineBtn = (Button) findViewById(R.id.btn_select_line);
        mSelectLineBtn.setOnClickListener(this);
        mUnHoldBtn = (Button) findViewById(R.id.btn_unhold);
        mUnHoldBtn.setOnClickListener(this);

        mSelectedLine = null;
        mPrevStatus = -1;
        startMonitorCallLines();
        initializeTone();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopMonitorCallLines();
        releaseTone();
    }

    @Override
    public void onClick(View v) {
        if (mSelectedLine != null) {
            if (R.id.btn_accept == v.getId() && mSelectedLine.getStatus() == 2) {
                BaseCallApi.acceptCall(mSelectedLine.getLineId(), false, false);
            } else if (R.id.btn_end == v.getId() && mSelectedLine.getStatus() != 0) {
                BaseCallApi.endCall(mSelectedLine.getLineId());
            } else if (R.id.btn_transfer == v.getId() && mSelectedLine.getStatus() == 4) {
                BaseCallApi.holdUnholdLine(mSelectedLine.getLineId());
                v.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent();
                        intent.setClass(TalkingActivity.this, TransferActivity.class);
                        intent.putExtra("lineId", mSelectedLine.getLineId());
                        startActivityForResult(intent, 0);
                    }
                }, 200);
            } else if (R.id.btn_transfer_now == v.getId()) {
                if (mTransferTargetLine == null) {
                    return;
                }
                if (mTransferTargetLine.getStatus() == 3 || mTransferTargetLine.getStatus() == 12) {
                    BaseCallApi.endCall(mSelectedLine.getLineId());
                    finishAttendTransfer();
                } else if (mTransferTargetLine.getStatus() == 4) {
                    BaseCallApi.transferAttendedEnd(mTransferTargetLine.getLineId());
                    finishAttendTransfer();
                }
            } else if (R.id.btn_cancel == v.getId()) {
                if (mTransferTargetLine == null) {
                    return;
                }
                if (mTransferTargetLine.getStatus() == 3 || mTransferTargetLine.getStatus() == 12) {
                    BaseCallApi.transferAttendedCancel(mSelectedLine.getLineId());
                    finishAttendTransfer();
                } else if (mTransferTargetLine.getStatus() == 4) {
                    if (BaseCallApi.transferSplit()) {
                        BaseCallApi.endCall(mTransferTargetLine.getLineId());
                        finishAttendTransfer();
                    }
                }
            } else if (R.id.btn_split == v.getId()) {
                if (mTransferTargetLine != null && mTransferTargetLine.getStatus() == 4) {
                    BaseCallApi.transferSplit();
                    finishAttendTransfer();
                }
            } else if (R.id.btn_select_line == v.getId()) {
                onClickSelectLine();
            } else if (R.id.btn_unhold == v.getId()) {
                if (mSelectedLine.getStatus() == 5) {
                    BaseCallApi.holdUnholdLine(mSelectedLine.getLineId());
                }
            }
        }
    }

    public void onClickSelectLine() {
        final List<BaseLine> lines = BaseLineApi.getAllLines();
        if (lines == null || lines.size() == 0) {
            Toast.makeText(this, "has no lines", Toast.LENGTH_SHORT).show();
            return;
        }

        List<String> lineNames = new ArrayList<String>(lines.size());
        for (int i = 0; i < lines.size(); i++) {
            BaseLine line = lines.get(i);
            if (line.getStatus() == 0) {
                break;
            }
            lineNames.add("line id " + line.getLineId() + ": " + line.getRemoteName());
        }

        final String[] items = lineNames.toArray(new String[]{});
        AlertDialog.Builder listDialog =
                new AlertDialog.Builder(this);
        listDialog.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (isInAttendTransfer) {
                    Toast.makeText(TalkingActivity.this, "Can't select line before attend transfer finished", Toast.LENGTH_SHORT).show();
                    return;
                }
                mNumberTv.setText("remote number:" + lines.get(which).getRemoteNumber());
                mNameTv.setText("remote name:" + lines.get(which).getRemoteName());
                mStatusTv.setText("status:" + String.valueOf(lines.get(which).getStatus()));
                mSelectedLine = lines.get(which);
                updateBtns();
            }
        });
        listDialog.show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == 1) {
            isInAttendTransfer = true;
            mEndBtn.setVisibility(View.GONE);
            mTransBtn.setVisibility(View.GONE);
        }
    }

    private ToneGenerator mToneGenerator;
    private void initializeTone() {
        try {
            mToneGenerator = new ToneGenerator(AudioManager.STREAM_SYSTEM, ToneGenerator.MAX_VOLUME * 8 /10);
        } catch (Throwable ex) {
            Log.w(TAG, "Exception caught while creating tone generator: ", ex);
            mToneGenerator = null;
        }
    }

    private void releaseTone() {
        if (mToneGenerator != null) {
            mToneGenerator.release();
            mToneGenerator = null;
        }
    }

    private void startTone() {
        ToneGenerator tg = mToneGenerator;
        if (tg != null) {
            tg.startTone(ToneGenerator.TONE_SUP_RINGTONE);
        }
    }

    private void stopTone() {
        ToneGenerator tg = mToneGenerator;
        if (tg != null) {
            tg.stopTone();
        }
    }

    /////////////////////////////////////////////////////
    //
    // Handset Monitor and Call Line Monitor
    //
    /////////////////////////////////////////////////////

    private void startMonitorCallLines() {
        mCallStatusListener = new MyCallStatusListener();
        BaseCallApi.addStatusListener("com.gs.apidemo.MonitorCall", mCallStatusListener.callback,
                PhoneContext.ListenType.LINE_ID | PhoneContext.ListenType.LINE_STATUS,true);
    }

    private void stopMonitorCallLines() {
        BaseCallApi.removeStatusListener(mCallStatusListener.callback);
        mCallStatusListener.destroy();
        mCallStatusListener = null;
    }

    private class MyCallStatusListener extends CallStatusListener {
        @Override
        public void onLineStatusChanged(int notifyType, BaseLine baseLine, List<BaseLine> list) {
            Log.i(TAG, "notifyType "+notifyType);
            Log.i(TAG, "lineInfo "+baseLine);

            final BaseLine line = baseLine;

            if (mSelectedLine == null || mSelectedLine.getLineId() == line.getLineId()) {
                mSelectedLine = line;
                mNumberTv.setText("remote number:" + line.getRemoteNumber());
                mNameTv.setText("remote name:" + line.getRemoteName());
                mStatusTv.setText("status:" + String.valueOf(line.getStatus()));
                mPrevStatus = line.getStatus();
                updateBtns();
                if (line.getStatus() == PhoneContext.LineStatus.RINGING) { // ringing
                    if (CallSettingApi.isAlwaysRingSpeaker()) {
                        AudioRouteApi.switchCurrentVoiceWithSpeaker();
                    }
                    // start ringing
                    startTone();
                    Log.i(TAG, "onLineStatusChanged: Start Ringing tone");
                } else {
                    stopTone();
                }

                if (line.getStatus() == PhoneContext.LineStatus.TRANSFERED && line.getErrCode() == 2) {
                    //transfer failed. eg: the target line rejected call
                    Toast.makeText(TalkingActivity.this, "Transfer failed!", Toast.LENGTH_SHORT).show();
                    finishAttendTransfer();
                }
                if (isInAttendTransfer) {
                    if (line.getStatus() == 0) {
                        finishAttendTransfer();
                    }
                }
            } else if (isInAttendTransfer) {
                if (mTransferTargetLine == null && line.getStatus() == PhoneContext.LineStatus.CALLING) {
                    mTransferTargetLine = line;
                } else if (mTransferTargetLine != null && mTransferTargetLine.getLineId() == line.getLineId()) {
                    mTransferTargetLine = line;
                } else {
                    return;
                }
                if (mTransferTargetLine.getStatus() == PhoneContext.LineStatus.IDLE) {
                    finishAttendTransfer();
                }
                updateBtns();
            }
        }
    }

    private void updateBtns() {
        if (mSelectedLine == null) {
            mAcceptBtn.setVisibility(View.GONE);
            mTransBtn.setVisibility(View.GONE);
            mEndBtn.setVisibility(View.GONE);
            mTransferNowBtn.setVisibility(View.GONE);
            mSplitBtn.setVisibility(View.GONE);
            mCancelBtn.setVisibility(View.GONE);
        }
        if (isInAttendTransfer) {
            if (mTransferTargetLine != null) {
                if ((mTransferTargetLine.getStatus() == PhoneContext.LineStatus.CALLING || mTransferTargetLine.getStatus() == PhoneContext.LineStatus.RINGBACK)) {
                    //The transfer target line is calling or ringback
                    mTransferNowBtn.setVisibility(View.VISIBLE);
                    mSplitBtn.setVisibility(View.GONE);
                    mCancelBtn.setVisibility(View.VISIBLE);
                } else if (mTransferTargetLine.getStatus() == PhoneContext.LineStatus.CONNECTED) {
                    //The transfer target line is connected
                    mTransferNowBtn.setVisibility(View.VISIBLE);
                    mSplitBtn.setVisibility(View.VISIBLE);
                    mCancelBtn.setVisibility(View.VISIBLE);
                }
            }
            mAcceptBtn.setVisibility(View.GONE);
            mEndBtn.setVisibility(View.VISIBLE);
            mUnHoldBtn.setVisibility(View.GONE);
        } else {
            if (mSelectedLine.getStatus() == PhoneContext.LineStatus.RINGING) { // ringing
                mAcceptBtn.setVisibility(View.VISIBLE);
            } else {
                mAcceptBtn.setVisibility(View.GONE);
            }

            if (mSelectedLine.getStatus() == PhoneContext.LineStatus.IDLE) {
                mTransBtn.setVisibility(View.GONE);
                mEndBtn.setVisibility(View.GONE);
            } else if (mSelectedLine.getStatus() == PhoneContext.LineStatus.CONNECTED) {
                mTransBtn.setVisibility(View.VISIBLE);
                mEndBtn.setVisibility(View.VISIBLE);
            } else {
                mTransBtn.setVisibility(View.GONE);
                mEndBtn.setVisibility(View.VISIBLE);
            }
            mTransferNowBtn.setVisibility(View.GONE);
            mSplitBtn.setVisibility(View.GONE);
            mCancelBtn.setVisibility(View.GONE);

            if (mSelectedLine.getStatus() == PhoneContext.LineStatus.ONHOLD) {
                mUnHoldBtn.setVisibility(View.VISIBLE);
            } else {
                mUnHoldBtn.setVisibility(View.GONE);
            }
        }
    }

    public void finishAttendTransfer() {
        isInAttendTransfer = false;
        mTransferNowBtn.setVisibility(View.GONE);
        mSplitBtn.setVisibility(View.GONE);
        mCancelBtn.setVisibility(View.GONE);
    }

    private CallStatusListener mCallStatusListener = null;
}
