/*
 * Copyright (C) 2013 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 android.webkit;

import android.annotation.SystemApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * Helper class to create JavaScript dialogs. It is used by
 * different WebView implementations.
 *
 * @hide
 */
@SystemApi
public class JsDialogHelper {

    private static final String TAG = "JsDialogHelper";

    // Dialog types
    public static final int ALERT   = 1;
    public static final int CONFIRM = 2;
    public static final int PROMPT  = 3;
    public static final int UNLOAD  = 4;

    private final String mDefaultValue;
    private final JsPromptResult mResult;
    private final String mMessage;
    private final int mType;
    private final String mUrl;

    public JsDialogHelper(JsPromptResult result, int type, String defaultValue, String message,
            String url) {
        mResult = result;
        mDefaultValue = defaultValue;
        mMessage = message;
        mType = type;
        mUrl = url;
    }

    public JsDialogHelper(JsPromptResult result, Message msg) {
        mResult = result;
        mDefaultValue = msg.getData().getString("default");
        mMessage = msg.getData().getString("message");
        mType = msg.getData().getInt("type");
        mUrl = msg.getData().getString("url");
    }

    public boolean invokeCallback(WebChromeClient client, WebView webView) {
        switch (mType) {
            case ALERT:
                return client.onJsAlert(webView, mUrl, mMessage, mResult);
            case CONFIRM:
                return client.onJsConfirm(webView, mUrl, mMessage, mResult);
            case UNLOAD:
                return client.onJsBeforeUnload(webView, mUrl, mMessage, mResult);
            case PROMPT:
                return client.onJsPrompt(webView, mUrl, mMessage, mDefaultValue, mResult);
            default:
                throw new IllegalArgumentException("Unexpected type: " + mType);
        }
    }

    public void showDialog(Context context) {
        if (!canShowAlertDialog(context)) {
            Log.w(TAG, "Cannot create a dialog, the WebView context is not an Activity");
            mResult.cancel();
            return;
        }

        String title, displayMessage;
        int positiveTextId, negativeTextId;
        if (mType == UNLOAD) {
            title = context.getString(com.android.internal.R.string.js_dialog_before_unload_title);
            displayMessage = context.getString(
                    com.android.internal.R.string.js_dialog_before_unload, mMessage);
            positiveTextId = com.android.internal.R.string.js_dialog_before_unload_positive_button;
            negativeTextId = com.android.internal.R.string.js_dialog_before_unload_negative_button;
        } else {
            title = getJsDialogTitle(context);
            displayMessage = mMessage;
            positiveTextId = com.android.internal.R.string.ok;
            negativeTextId = com.android.internal.R.string.cancel;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(title);
        builder.setOnCancelListener(new CancelListener());
        if (mType != PROMPT) {
            builder.setMessage(displayMessage);
            builder.setPositiveButton(positiveTextId, new PositiveListener(null));
        } else {
            final View view = LayoutInflater.from(context).inflate(
                    com.android.internal.R.layout.js_prompt, null);
            EditText edit = ((EditText) view.findViewById(com.android.internal.R.id.value));
            edit.setText(mDefaultValue);
            builder.setPositiveButton(positiveTextId, new PositiveListener(edit));
            ((TextView) view.findViewById(com.android.internal.R.id.message)).setText(mMessage);
            builder.setView(view);
        }
        if (mType != ALERT) {
            builder.setNegativeButton(negativeTextId, new CancelListener());
        }
        builder.show();
    }

    private class CancelListener implements DialogInterface.OnCancelListener,
            DialogInterface.OnClickListener {
        @Override
        public void onCancel(DialogInterface dialog) {
            mResult.cancel();
        }
        @Override
        public void onClick(DialogInterface dialog, int which) {
            mResult.cancel();
        }
    }

    private class PositiveListener implements DialogInterface.OnClickListener {
        private final EditText mEdit;

        public PositiveListener(EditText edit) {
            mEdit = edit;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (mEdit == null) {
                mResult.confirm();
            } else {
                mResult.confirm(mEdit.getText().toString());
            }
        }
    }

    private String getJsDialogTitle(Context context) {
        String title = mUrl;
        if (URLUtil.isDataUrl(mUrl)) {
            // For data: urls, we just display 'JavaScript' similar to Chrome.
            title = context.getString(com.android.internal.R.string.js_dialog_title_default);
        } else {
            try {
                URL alertUrl = new URL(mUrl);
                // For example: "The page at 'http://www.mit.edu' says:"
                title = context.getString(com.android.internal.R.string.js_dialog_title,
                        alertUrl.getProtocol() + "://" + alertUrl.getHost());
            } catch (MalformedURLException ex) {
                // do nothing. just use the url as the title
            }
        }
        return title;
    }

    private static boolean canShowAlertDialog(Context context) {
        // We can only display the alert dialog if mContext is
        // an Activity context.
        // FIXME: Should we display dialogs if mContext does
        // not have the window focus (e.g. if the user is viewing
        // another Activity when the alert should be displayed) ?
        // See bug 3166409
        return context instanceof Activity;
    }
}
