/*
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.android.bluetooth.opp;

import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.android.bluetooth.R;
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;

/**
 * Handle all transfer related dialogs: -Ongoing transfer -Receiving one file
 * dialog -Sending one file dialog -sending multiple files dialog -Complete
 * transfer -receive -receive success, will trigger corresponding handler
 * -receive fail dialog -send -send success dialog -send fail dialog -Other
 * dialogs - - DIALOG_RECEIVE_ONGOING will transition to
 * DIALOG_RECEIVE_COMPLETE_SUCCESS or DIALOG_RECEIVE_COMPLETE_FAIL
 * DIALOG_SEND_ONGOING will transition to DIALOG_SEND_COMPLETE_SUCCESS or
 * DIALOG_SEND_COMPLETE_FAIL
 */
public class BluetoothOppTransferActivity extends AlertActivity
        implements DialogInterface.OnClickListener {
    private static final String TAG = "BluetoothOppTransferActivity";
    private static final boolean D = Constants.DEBUG;
    private static final boolean V = Constants.VERBOSE;

    private Uri mUri;

    // ongoing transfer-0 complete transfer-1
    boolean mIsComplete;

    private BluetoothOppTransferInfo mTransInfo;

    private ProgressBar mProgressTransfer;

    private TextView mPercentView;

    private AlertController.AlertParams mPara;

    private View mView = null;

    private TextView mLine1View, mLine2View, mLine3View, mLine5View;

    private int mWhichDialog;

    private BluetoothAdapter mAdapter;

    // Dialogs definition:
    // Receive progress dialog
    public static final int DIALOG_RECEIVE_ONGOING = 0;

    // Receive complete and success dialog
    public static final int DIALOG_RECEIVE_COMPLETE_SUCCESS = 1;

    // Receive complete and fail dialog: will display some fail reason
    public static final int DIALOG_RECEIVE_COMPLETE_FAIL = 2;

    // Send progress dialog
    public static final int DIALOG_SEND_ONGOING = 3;

    // Send complete and success dialog
    public static final int DIALOG_SEND_COMPLETE_SUCCESS = 4;

    // Send complete and fail dialog: will let user retry
    public static final int DIALOG_SEND_COMPLETE_FAIL = 5;

    /** Observer to get notified when the content observer's data changes */
    private BluetoothTransferContentObserver mObserver;

    // do not update button during activity creating, only update when db
    // changes after activity created
    private boolean mNeedUpdateButton = false;

    private class BluetoothTransferContentObserver extends ContentObserver {
        BluetoothTransferContentObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            if (V) {
                Log.v(TAG, "received db changes.");
            }
            mNeedUpdateButton = true;
            updateProgressbar();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        mUri = intent.getData();

        mTransInfo = new BluetoothOppTransferInfo();
        mTransInfo = BluetoothOppUtility.queryRecord(this, mUri);
        if (mTransInfo == null) {
            if (V) {
                Log.e(TAG, "Error: Can not get data from db");
            }
            finish();
            return;
        }

        mIsComplete = BluetoothShare.isStatusCompleted(mTransInfo.mStatus);

        displayWhichDialog();

        // update progress bar for ongoing transfer
        if (!mIsComplete) {
            mObserver = new BluetoothTransferContentObserver();
            getContentResolver().registerContentObserver(BluetoothShare.CONTENT_URI, true,
                    mObserver);
        }

        if (mWhichDialog != DIALOG_SEND_ONGOING && mWhichDialog != DIALOG_RECEIVE_ONGOING) {
            // set this record to INVISIBLE
            BluetoothOppUtility.updateVisibilityToHidden(this, mUri);
        }

        mAdapter = BluetoothAdapter.getDefaultAdapter();

        // Set up the "dialog"
        setUpDialog();
    }

    @Override
    protected void onDestroy() {
        if (D) {
            Log.d(TAG, "onDestroy()");
        }

        if (mObserver != null) {
            getContentResolver().unregisterContentObserver(mObserver);
        }
        super.onDestroy();
    }

    private void displayWhichDialog() {
        int direction = mTransInfo.mDirection;
        boolean isSuccess = BluetoothShare.isStatusSuccess(mTransInfo.mStatus);
        boolean isComplete = BluetoothShare.isStatusCompleted(mTransInfo.mStatus);

        if (direction == BluetoothShare.DIRECTION_INBOUND) {
            if (isComplete) {
                if (isSuccess) {
                    // should not go here
                    mWhichDialog = DIALOG_RECEIVE_COMPLETE_SUCCESS;
                } else if (!isSuccess) {
                    mWhichDialog = DIALOG_RECEIVE_COMPLETE_FAIL;
                }
            } else if (!isComplete) {
                mWhichDialog = DIALOG_RECEIVE_ONGOING;
            }
        } else if (direction == BluetoothShare.DIRECTION_OUTBOUND) {
            if (isComplete) {
                if (isSuccess) {
                    mWhichDialog = DIALOG_SEND_COMPLETE_SUCCESS;

                } else if (!isSuccess) {
                    mWhichDialog = DIALOG_SEND_COMPLETE_FAIL;
                }
            } else if (!isComplete) {
                mWhichDialog = DIALOG_SEND_ONGOING;
            }
        }

        if (V) {
            Log.v(TAG, " WhichDialog/dir/isComplete/failOrSuccess" + mWhichDialog + direction
                    + isComplete + isSuccess);
        }
    }

    private void setUpDialog() {
        // final AlertController.AlertParams p = mAlertParams;
        mPara = mAlertParams;
        mPara.mTitle = getString(R.string.download_title);

        if ((mWhichDialog == DIALOG_RECEIVE_ONGOING) || (mWhichDialog == DIALOG_SEND_ONGOING)) {
            mPara.mPositiveButtonText = getString(R.string.download_ok);
            mPara.mPositiveButtonListener = this;
            mPara.mNegativeButtonText = getString(R.string.download_cancel);
            mPara.mNegativeButtonListener = this;
        } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) {
            mPara.mPositiveButtonText = getString(R.string.download_succ_ok);
            mPara.mPositiveButtonListener = this;
        } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) {
            mPara.mIconAttrId = android.R.attr.alertDialogIcon;
            mPara.mPositiveButtonText = getString(R.string.download_fail_ok);
            mPara.mPositiveButtonListener = this;
        } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) {
            mPara.mPositiveButtonText = getString(R.string.upload_succ_ok);
            mPara.mPositiveButtonListener = this;
        } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) {
            mPara.mIconAttrId = android.R.attr.alertDialogIcon;
            mPara.mPositiveButtonText = getString(R.string.upload_fail_ok);
            mPara.mPositiveButtonListener = this;
            mPara.mNegativeButtonText = getString(R.string.upload_fail_cancel);
            mPara.mNegativeButtonListener = this;
        }
        mPara.mView = createView();
        setupAlert();
    }

    private View createView() {

        mView = getLayoutInflater().inflate(R.layout.file_transfer, null);

        mProgressTransfer = (ProgressBar) mView.findViewById(R.id.progress_transfer);
        mPercentView = (TextView) mView.findViewById(R.id.progress_percent);

        customizeViewContent();

        // no need update button when activity creating
        mNeedUpdateButton = false;
        updateProgressbar();

        return mView;
    }

    /**
     * customize the content of view
     */
    private void customizeViewContent() {
        String tmp;

        if (mWhichDialog == DIALOG_RECEIVE_ONGOING
                || mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) {
            mLine1View = (TextView) mView.findViewById(R.id.line1_view);
            tmp = getString(R.string.download_line1, mTransInfo.mDeviceName);
            mLine1View.setText(tmp);
            mLine2View = (TextView) mView.findViewById(R.id.line2_view);
            tmp = getString(R.string.download_line2, mTransInfo.mFileName);
            mLine2View.setText(tmp);
            mLine3View = (TextView) mView.findViewById(R.id.line3_view);
            tmp = getString(R.string.download_line3,
                    Formatter.formatFileSize(this, mTransInfo.mTotalBytes));
            mLine3View.setText(tmp);
            mLine5View = (TextView) mView.findViewById(R.id.line5_view);
            if (mWhichDialog == DIALOG_RECEIVE_ONGOING) {
                tmp = getString(R.string.download_line5);
            } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) {
                tmp = getString(R.string.download_succ_line5);
            }
            mLine5View.setText(tmp);
        } else if (mWhichDialog == DIALOG_SEND_ONGOING
                || mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) {
            mLine1View = (TextView) mView.findViewById(R.id.line1_view);
            tmp = getString(R.string.upload_line1, mTransInfo.mDeviceName);
            mLine1View.setText(tmp);
            mLine2View = (TextView) mView.findViewById(R.id.line2_view);
            tmp = getString(R.string.download_line2, mTransInfo.mFileName);
            mLine2View.setText(tmp);
            mLine3View = (TextView) mView.findViewById(R.id.line3_view);
            tmp = getString(R.string.upload_line3, mTransInfo.mFileType,
                    Formatter.formatFileSize(this, mTransInfo.mTotalBytes));
            mLine3View.setText(tmp);
            mLine5View = (TextView) mView.findViewById(R.id.line5_view);
            if (mWhichDialog == DIALOG_SEND_ONGOING) {
                tmp = getString(R.string.upload_line5);
            } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) {
                tmp = getString(R.string.upload_succ_line5);
            }
            mLine5View.setText(tmp);
        } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) {
            if (mTransInfo.mStatus == BluetoothShare.STATUS_ERROR_SDCARD_FULL) {
                mLine1View = (TextView) mView.findViewById(R.id.line1_view);
                int id = BluetoothOppUtility.deviceHasNoSdCard()
                        ? R.string.bt_sm_2_1_nosdcard
                        : R.string.bt_sm_2_1_default;
                tmp = getString(id);
                mLine1View.setText(tmp);
                mLine2View = (TextView) mView.findViewById(R.id.line2_view);
                tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName);
                mLine2View.setText(tmp);
                mLine3View = (TextView) mView.findViewById(R.id.line3_view);
                tmp = getString(R.string.bt_sm_2_2,
                        Formatter.formatFileSize(this, mTransInfo.mTotalBytes));
                mLine3View.setText(tmp);
            } else {
                mLine1View = (TextView) mView.findViewById(R.id.line1_view);
                tmp = getString(R.string.download_fail_line1);
                mLine1View.setText(tmp);
                mLine2View = (TextView) mView.findViewById(R.id.line2_view);
                tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName);
                mLine2View.setText(tmp);
                mLine3View = (TextView) mView.findViewById(R.id.line3_view);
                tmp = getString(R.string.download_fail_line3,
                        BluetoothOppUtility.getStatusDescription(this, mTransInfo.mStatus,
                                mTransInfo.mDeviceName));
                mLine3View.setText(tmp);
            }
            mLine5View = (TextView) mView.findViewById(R.id.line5_view);
            mLine5View.setVisibility(View.GONE);
        } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) {
            mLine1View = (TextView) mView.findViewById(R.id.line1_view);
            tmp = getString(R.string.upload_fail_line1, mTransInfo.mDeviceName);
            mLine1View.setText(tmp);
            mLine2View = (TextView) mView.findViewById(R.id.line2_view);
            tmp = getString(R.string.upload_fail_line1_2, mTransInfo.mFileName);
            mLine2View.setText(tmp);
            mLine3View = (TextView) mView.findViewById(R.id.line3_view);
            tmp = getString(R.string.download_fail_line3,
                    BluetoothOppUtility.getStatusDescription(this, mTransInfo.mStatus,
                            mTransInfo.mDeviceName));
            mLine3View.setText(tmp);
            mLine5View = (TextView) mView.findViewById(R.id.line5_view);
            mLine5View.setVisibility(View.GONE);
        }

        if (BluetoothShare.isStatusError(mTransInfo.mStatus)) {
            mProgressTransfer.setVisibility(View.GONE);
            mPercentView.setVisibility(View.GONE);
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) {
                    // "Open" - open receive file
                    BluetoothOppUtility.openReceivedFile(this, mTransInfo.mFileName,
                            mTransInfo.mFileType, mTransInfo.mTimeStamp, mUri);

                    // make current transfer "hidden"
                    BluetoothOppUtility.updateVisibilityToHidden(this, mUri);

                    // clear correspondent notification item
                    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(
                            mTransInfo.mID);
                } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) {
                    // "try again"
                    // make current transfer "hidden"
                    BluetoothOppUtility.updateVisibilityToHidden(this, mUri);

                    // clear correspondent notification item
                    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(
                            mTransInfo.mID);
                    retryFailedTrasfer();
                    BluetoothDevice remoteDevice = mAdapter.getRemoteDevice(mTransInfo.mDestAddr);

                    // Display toast message
                    Toast.makeText(this, this.getString(R.string.bt_toast_4,
                            BluetoothOppManager.getInstance(this).getDeviceName(remoteDevice)),
                            Toast.LENGTH_SHORT).show();

                } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) {
                    BluetoothOppUtility.updateVisibilityToHidden(this, mUri);
                    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(
                            mTransInfo.mID);
                }
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                if (mWhichDialog == DIALOG_RECEIVE_ONGOING || mWhichDialog == DIALOG_SEND_ONGOING) {
                    // "Stop" button
                    this.getContentResolver().delete(mUri, null, null);

                    String msg = "";
                    if (mWhichDialog == DIALOG_RECEIVE_ONGOING) {
                        msg = getString(R.string.bt_toast_3, mTransInfo.mDeviceName);
                    } else if (mWhichDialog == DIALOG_SEND_ONGOING) {
                        msg = getString(R.string.bt_toast_6, mTransInfo.mDeviceName);
                    }
                    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();

                    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(
                            mTransInfo.mID);
                } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) {

                    BluetoothOppUtility.updateVisibilityToHidden(this, mUri);
                }
                break;
        }
        finish();
    }

    /**
     * Update progress bar per data got from content provider
     */
    private void updateProgressbar() {
        mTransInfo = BluetoothOppUtility.queryRecord(this, mUri);
        if (mTransInfo == null) {
            if (V) {
                Log.e(TAG, "Error: Can not get data from db");
            }
            return;
        }

        // Set Transfer Max as 100. Percentage calculation would be done in setProgress API
        mProgressTransfer.setMax(100);

        if (mTransInfo.mTotalBytes != 0) {
            if (V) {
                Log.v(TAG, "mCurrentBytes: " + mTransInfo.mCurrentBytes + " mTotalBytes: "
                        + mTransInfo.mTotalBytes + " (" + (int) ((mTransInfo.mCurrentBytes * 100)
                        / mTransInfo.mTotalBytes) + "%)");
            }
            mProgressTransfer.setProgress(
                    (int) ((mTransInfo.mCurrentBytes * 100) / mTransInfo.mTotalBytes));
        } else {
            mProgressTransfer.setProgress(100);
        }

        mPercentView.setText(BluetoothOppUtility.formatProgressText(mTransInfo.mTotalBytes,
                mTransInfo.mCurrentBytes));

        // Handle the case when DIALOG_RECEIVE_ONGOING evolve to
        // DIALOG_RECEIVE_COMPLETE_SUCCESS/DIALOG_RECEIVE_COMPLETE_FAIL
        // Handle the case when DIALOG_SEND_ONGOING evolve to
        // DIALOG_SEND_COMPLETE_SUCCESS/DIALOG_SEND_COMPLETE_FAIL
        if (!mIsComplete && BluetoothShare.isStatusCompleted(mTransInfo.mStatus)
                && mNeedUpdateButton) {
            if (mObserver != null) {
                getContentResolver().unregisterContentObserver(mObserver);
                mObserver = null;
            }
            displayWhichDialog();
            updateButton();
            customizeViewContent();
        }
    }

    /**
     * Update button when one transfer goto complete from ongoing
     */
    private void updateButton() {
        if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) {
            mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
            mAlert.getButton(DialogInterface.BUTTON_POSITIVE)
                    .setText(getString(R.string.download_succ_ok));
        } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) {
            mAlert.setIcon(mAlert.getIconAttributeResId(android.R.attr.alertDialogIcon));
            mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
            mAlert.getButton(DialogInterface.BUTTON_POSITIVE)
                    .setText(getString(R.string.download_fail_ok));
        } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) {
            mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
            mAlert.getButton(DialogInterface.BUTTON_POSITIVE)
                    .setText(getString(R.string.upload_succ_ok));
        } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) {
            mAlert.setIcon(mAlert.getIconAttributeResId(android.R.attr.alertDialogIcon));
            mAlert.getButton(DialogInterface.BUTTON_POSITIVE)
                    .setText(getString(R.string.upload_fail_ok));
            mAlert.getButton(DialogInterface.BUTTON_NEGATIVE)
                    .setText(getString(R.string.upload_fail_cancel));
        }
    }

   /*
    * Retry the failed transfer in background thread
    */
   private void retryFailedTrasfer() {
        new Thread() {
            @Override
            public void run() {
                Uri uri = BluetoothOppUtility.originalUri(Uri.parse(mTransInfo.mFileUri));
                BluetoothOppSendFileInfo sendFileInfo =
                        BluetoothOppSendFileInfo.generateFileInfo(BluetoothOppTransferActivity
                        .this, uri, mTransInfo.mFileType, false);
                uri = BluetoothOppUtility.generateUri(uri, sendFileInfo);
                BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo);
                mTransInfo.mFileUri = uri.toString();
                BluetoothOppUtility.retryTransfer(BluetoothOppTransferActivity.this, mTransInfo);
            }
        }.start();
    }
}
