// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

import com.google.common.annotations.VisibleForTesting;

import org.chromium.base.CalledByNative;
import org.chromium.chrome.R;
import org.chromium.ui.gfx.NativeWindow;

public class JavascriptAppModalDialog implements DialogInterface.OnClickListener {
    private static final String TAG = JavascriptAppModalDialog.class.getName();

    private String mTitle;
    private String mMessage;
    private boolean mShouldShowSuppressCheckBox;
    private int mNativeDialogPointer;
    private AlertDialog mDialog;
    private CheckBox mSuppressCheckBox;
    private TextView mPrompTextView;

    private JavascriptAppModalDialog(String title, String message,
            boolean shouldShowSuppressCheckBox) {
        mTitle = title;
        mMessage = message;
        mShouldShowSuppressCheckBox = shouldShowSuppressCheckBox;
    }

    @CalledByNative
    public static JavascriptAppModalDialog createAlertDialog(String title, String message,
            boolean shouldShowSuppressCheckBox) {
        return new JavascriptAppAlertDialog(title, message, shouldShowSuppressCheckBox);
    }

    @CalledByNative
    public static JavascriptAppModalDialog createConfirmDialog(String title, String message,
            boolean shouldShowSuppressCheckBox) {
        return new JavascriptAppConfirmDialog(title, message, shouldShowSuppressCheckBox);
    }

    @CalledByNative
    public static JavascriptAppModalDialog createBeforeUnloadDialog(String title, String message,
            boolean isReload, boolean shouldShowSuppressCheckBox) {
        return new JavascriptAppBeforeUnloadDialog(title, message, isReload,
                shouldShowSuppressCheckBox);
    }

    @CalledByNative
    public static JavascriptAppModalDialog createPromptDialog(String title, String message,
            boolean shouldShowSuppressCheckBox, String defaultPromptText) {
        return new JavascriptAppPromptDialog(title, message, shouldShowSuppressCheckBox,
                defaultPromptText);
    }

    @CalledByNative
    void showJavascriptAppModalDialog(NativeWindow window, int nativeDialogPointer) {
        assert window != null;
        Context context = window.getContext();

        // Cache the native dialog pointer so that we can use it to return the response.
        mNativeDialogPointer = nativeDialogPointer;

        LayoutInflater inflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.js_modal_dialog, null);
        mSuppressCheckBox = (CheckBox) layout.findViewById(R.id.suppress_js_modal_dialogs);
        mPrompTextView = (TextView) layout.findViewById(R.id.js_modal_dialog_prompt);

        prepare(layout);

        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context)
                .setView(layout)
                .setTitle(mTitle)
                .setMessage(mMessage)
                .setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        cancel(false);
                    }
                });
        if (hasPositiveButton()) {
            dialogBuilder.setPositiveButton(getPositiveButtonText(), this);
        }
        if (hasNegativeButton()) {
            dialogBuilder.setNegativeButton(getNegativeButtonText(), this);
        }

        mDialog = dialogBuilder.create();
        mDialog.setCanceledOnTouchOutside(false);
        mDialog.show();
    }

   @Override
   public void onClick(DialogInterface dialog, int which) {
       switch (which) {
           case DialogInterface.BUTTON_POSITIVE:
               onPositiveButtonClicked();
               break;
           case DialogInterface.BUTTON_NEGATIVE:
               onNegativeButtonClicked();
               break;
           default:
               Log.e(TAG, "Unexpected button pressed in dialog: " + which);
       }
   }

    @CalledByNative
    void dismiss() {
        mDialog.dismiss();
    }

    /**
     * Returns the currently showing dialog, null if none is showing.
     */
    @VisibleForTesting
    public static JavascriptAppPromptDialog getCurrentDialogForTest() {
        return nativeGetCurrentModalDialog();
    }


    /**
     * Returns the AlertDialog associated with this JavascriptAppPromptDialog.
     */
    @VisibleForTesting
    public AlertDialog getDialogForTest() {
        return mDialog;
    }

    // Methods that subclasses should override to set buttons behavior.
    public boolean hasPositiveButton() {
        return false;
    }

    public int getPositiveButtonText() {
        return -1;
    }

    public boolean hasNegativeButton() {
        return false;
    }

    public int getNegativeButtonText() {
        return -1;
    }

    public void onPositiveButtonClicked() {
        confirm(mPrompTextView.getText().toString(), mSuppressCheckBox.isChecked());
        mDialog.dismiss();
    }

    public void onNegativeButtonClicked() {
        cancel(mSuppressCheckBox.isChecked());
        mDialog.dismiss();
    }

    void prepare(final ViewGroup layout) {
        // Display the checkbox for supressing dialogs if necessary.
        layout.findViewById(R.id.suppress_js_modal_dialogs).setVisibility(
                mShouldShowSuppressCheckBox ? View.VISIBLE : View.GONE);
    }

    public void confirm(String promptResult, boolean suppressDialogs) {
        nativeDidAcceptAppModalDialog(mNativeDialogPointer, promptResult, suppressDialogs);
    }

    public void cancel(boolean suppressDialogs) {
        nativeDidCancelAppModalDialog(mNativeDialogPointer, suppressDialogs);
    }

    private static class JavascriptAppAlertDialog extends JavascriptAppModalDialog {
        public JavascriptAppAlertDialog(String title, String message,
                boolean shouldShowSuppressCheckBox) {
            super(title, message, shouldShowSuppressCheckBox);
        }

        @Override
        public boolean hasPositiveButton() {
            return true;
        }

        @Override
        public int getPositiveButtonText() {
            return R.string.js_modal_dialog_confirm;
        }
    }

    private static class JavascriptAppConfirmDialog extends JavascriptAppAlertDialog {
        public JavascriptAppConfirmDialog(String title, String message,
                boolean shouldShowSuppressCheckBox) {
            super(title, message, shouldShowSuppressCheckBox);
        }

        @Override
        public boolean hasNegativeButton() {
            return true;
        }

        @Override
        public int getNegativeButtonText() {
            return R.string.js_modal_dialog_cancel;
        }
    }

    private static class JavascriptAppBeforeUnloadDialog extends JavascriptAppConfirmDialog {
        private boolean mIsReload;

        public JavascriptAppBeforeUnloadDialog(String title, String message,
                boolean isReload, boolean shouldShowSuppressCheckBox) {
            super(title, message, shouldShowSuppressCheckBox);
            mIsReload = isReload;
        }

        @Override
        public boolean hasPositiveButton() {
            return true;
        }

        @Override
        public int getPositiveButtonText() {
            return mIsReload ? R.string.reload_this_page : R.string.leave_this_page;
        }

        @Override
        public boolean hasNegativeButton() {
            return true;
        }

        @Override
        public int getNegativeButtonText() {
            return mIsReload ? R.string.dont_reload_this_page : R.string.stay_on_this_page;
        }
    }

    private static class JavascriptAppPromptDialog extends JavascriptAppConfirmDialog {
        private String mDefaultPromptText;

        public JavascriptAppPromptDialog(String title, String message,
                boolean shouldShowSuppressCheckBox, String defaultPromptText) {
            super(title, message, shouldShowSuppressCheckBox);
            mDefaultPromptText = defaultPromptText;
        }

        @Override
        public void prepare(ViewGroup layout) {
            super.prepare(layout);
            EditText prompt = (EditText) layout.findViewById(R.id.js_modal_dialog_prompt);
            prompt.setVisibility(View.VISIBLE);

            if (mDefaultPromptText.length() > 0) {
                prompt.setText(mDefaultPromptText);
                prompt.selectAll();
            }
        }
    }

    private native void nativeDidAcceptAppModalDialog(int nativeJavascriptAppModalDialogAndroid,
            String prompt, boolean suppress);

    private native void nativeDidCancelAppModalDialog(int nativeJavascriptAppModalDialogAndroid,
            boolean suppress);

    private static native JavascriptAppPromptDialog nativeGetCurrentModalDialog();
}

@@ -4730,30 +4730,29 @@
 avascriptApp
-Prompt
+Modal
 Dialog getCu
@@ -9305,30 +9305,29 @@
 avascriptApp
-Prompt
+Modal
 Dialog nativ

Fix ModalDialogTest tests.