/*
 * Copyright (C) 2006 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.browser;

import com.google.common.annotations.VisibleForTesting;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;

public class BrowserActivity extends Activity {

    public static final String ACTION_SHOW_BOOKMARKS = "show_bookmarks";
    public static final String ACTION_SHOW_BROWSER = "show_browser";
    public static final String ACTION_RESTART = "--restart--";
    private static final String EXTRA_STATE = "state";

    private final static String LOGTAG = "browser";

    private final static boolean LOGV_ENABLED =
            com.android.browser.Browser.LOGV_ENABLED;

    private Controller mController;
    private UI mUi;

    @Override
    public void onCreate(Bundle icicle) {
        if (LOGV_ENABLED) {
            Log.v(LOGTAG, this + " onStart");
        }
        super.onCreate(icicle);

        BrowserSettings settings = BrowserSettings.getInstance();

        // We load the first set of BrowserSettings from the db asynchronously
        // but if it has not completed at this point, we have no choice but
        // to block waiting for them to finish loading. :(
        settings.waitForLoadFromDbToComplete();

        // render the browser in OpenGL
        if (settings.isHardwareAccelerated()) {
            // Set the flag in the activity's window
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        } else {
            // Clear the flag in the activity's window
            this.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        }

        // enable this to test the browser in 32bit
        if (false) {
            getWindow().setFormat(PixelFormat.RGBX_8888);
            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
        }

        // If this was a web search request, pass it on to the default web
        // search provider and finish this activity.
        if (IntentHandler.handleWebSearchIntent(this, null, getIntent())) {
            finish();
            return;
        }

        if (((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
                .isEnabled()) {
            setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
        }

        mController = new Controller(this);
        boolean xlarge = (getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                == Configuration.SCREENLAYOUT_SIZE_XLARGE;
        if (xlarge) {
            mUi = new XLargeUi(this, mController);
        } else {
            mUi = new PhoneUi(this, mController);
        }
        mController.setUi(mUi);
        mController.setWebViewFactory((BaseUi) mUi);

        Bundle state = getIntent().getBundleExtra(EXTRA_STATE);
        if (state != null && icicle == null) {
            icicle = state;
        }

        String account = settings.getAutoLoginAccount(this);
        if (settings.isAutoLoginEnabled() && account != null &&
                !GoogleAccountLogin.isLoggedIn()) {
            GoogleAccountLogin login =
                    new GoogleAccountLogin(this, account);
            final ProgressDialog dialog = ProgressDialog.show(this,
                    getString(R.string.pref_autologin_title),
                    getString(R.string.pref_autologin_progress, account),
                    true /* indeterminate */,
                    true /* cancelable */,
                    login);
            final Bundle b = icicle;
            final Handler handler = new Handler();
            final Runnable dismiss = new Runnable() {
                @Override public void run() {
                    dialog.dismiss();
                }
            };
            final Runnable start = new Runnable() {
                @Override public void run() {
                    // Post a delayed dismiss message to avoid a flash of the
                    // progress dialog.
                    handler.postDelayed(dismiss, 1000);
                    mController.start(b, getIntent());
                }
            };
            login.startLogin(start);
        } else {
            mController.start(icicle, getIntent());
        }
    }

    @VisibleForTesting
    Controller getController() {
        return mController;
    }

    @Override
    protected void onNewIntent(Intent intent) {
        if (ACTION_RESTART.equals(intent.getAction())) {
            Bundle outState = new Bundle();
            mController.onSaveInstanceState(outState);
            finish();
            getApplicationContext().startActivity(
                    new Intent(getApplicationContext(), BrowserActivity.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .putExtra(EXTRA_STATE, outState));
            return;
        }
        mController.handleNewIntent(intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (LOGV_ENABLED) {
            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
        }
        if (mController != null) {
            mController.onResume();
        }
    }

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
            mController.onMenuOpened(featureId, menu);
        }
        return true;
    }

    @Override
    public void onOptionsMenuClosed(Menu menu) {
        mController.onOptionsMenuClosed(menu);
    }

    @Override
    public void onContextMenuClosed(Menu menu) {
        super.onContextMenuClosed(menu);
        mController.onContextMenuClosed(menu);
    }

    /**
     *  onSaveInstanceState(Bundle map)
     *  onSaveInstanceState is called right before onStop(). The map contains
     *  the saved state.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (LOGV_ENABLED) {
            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
        }
        mController.onSaveInstanceState(outState);
    }

    @Override
    protected void onPause() {
        if (mController != null) {
            mController.onPause();
        }
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (LOGV_ENABLED) {
            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
        }
        super.onDestroy();
        if (mController != null) {
            mController.onDestroy();
        }
        mUi = null;
        mController = null;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mController.onConfgurationChanged(newConfig);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mController.onLowMemory();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        return mController.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return mController.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (!mController.onOptionsItemSelected(item)) {
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        mController.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        return mController.onContextItemSelected(item);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return mController.onKeyDown(keyCode, event) ||
            super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        return mController.onKeyUp(keyCode, event) ||
            super.onKeyUp(keyCode, event);
    }

    @Override
    public void onActionModeStarted(ActionMode mode) {
        super.onActionModeStarted(mode);
        mController.onActionModeStarted(mode);
    }

    @Override
    public void onActionModeFinished(ActionMode mode) {
        super.onActionModeFinished(mode);
        mController.onActionModeFinished(mode);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        mController.onActivityResult(requestCode, resultCode, intent);
    }


}