/*
 * 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.support.v7.app;

import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.WindowCompat;
import android.support.v7.internal.view.ActionModeWrapper;
import android.support.v7.internal.view.menu.MenuWrapperFactory;
import android.support.v7.view.ActionMode;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;

class ActionBarActivityDelegateHC extends ActionBarActivityDelegate {
    Menu mMenu;

    ActionBarActivityDelegateHC(ActionBarActivity activity) {
        super(activity);
    }

    @Override
    public ActionBar createSupportActionBar() {
        return new ActionBarImplHC(mActivity, mActivity);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (mHasActionBar) {
            // If action bar is requested by inheriting from the appcompat theme,
            // the system will not know about that. So explicitly request for an action bar.
            mActivity.requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
        }
        if (mOverlayActionBar) {
            mActivity.requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
        }

        /*
         * This goofy move needs some explanation.
         *
         * The verifier on older platform versions has some interesting side effects if
         * a class defines a method that takes a parameter of a type that doesn't exist.
         * In this case, that type is android.view.ActionMode. Therefore, ActionBarActivity
         * cannot override the onActionModeStarted/Finished methods without causing nastiness
         * when it is loaded on older platform versions.
         *
         * Since these methods are actually part of the window callback and not intrinsic to
         * Activity itself, we can install a little shim with the window instead that knows
         * about the ActionMode class. Note that this means that any new methods added to
         * Window.Callback in the future won't get proxied without updating the support lib,
         * but we shouldn't be adding new methods to public interfaces that way anyway...right? ;)
         */
        final Window w = mActivity.getWindow();
        w.setCallback(createWindowCallbackWrapper(w.getCallback()));
    }

    Window.Callback createWindowCallbackWrapper(Window.Callback cb) {
        return new WindowCallbackWrapper(cb);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    }

    @Override
    public void onStop() {
    }

    @Override
    public void onPostResume() {
    }

    @Override
    public void setContentView(View v) {
        mActivity.superSetContentView(v);
    }

    @Override
    public void setContentView(int resId) {
        mActivity.superSetContentView(resId);
    }

    @Override
    public void setContentView(View v, ViewGroup.LayoutParams lp) {
        mActivity.superSetContentView(v, lp);
    }

    @Override
    public void addContentView(View v, ViewGroup.LayoutParams lp) {
        mActivity.superAddContentView(v, lp);
    }

    @Override
    public boolean supportRequestWindowFeature(int featureId) {
        return mActivity.requestWindowFeature(featureId);
    }

    @Override
    public View onCreatePanelView(int featureId) {
        // Do not create custom options menu on HC+
        return null;
    }

    @Override
    public boolean onCreatePanelMenu(int featureId, Menu menu) {
        if (featureId == Window.FEATURE_OPTIONS_PANEL || featureId == Window.FEATURE_ACTION_BAR) {
            if (mMenu == null) {
                mMenu = MenuWrapperFactory.createMenuWrapper(menu);
            }
            return mActivity.superOnCreatePanelMenu(featureId, mMenu);
        }
        return mActivity.superOnCreatePanelMenu(featureId, menu);
    }

    @Override
    public boolean onPreparePanel(int featureId, View view, Menu menu) {
        if (featureId == Window.FEATURE_OPTIONS_PANEL || featureId == Window.FEATURE_ACTION_BAR) {
            return mActivity.superOnPreparePanel(featureId, view, mMenu);
        }
        return mActivity.superOnPreparePanel(featureId, view, menu);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        if (featureId == Window.FEATURE_OPTIONS_PANEL) {
            item = MenuWrapperFactory.createMenuItemWrapper(item);
        }
        return mActivity.superOnMenuItemSelected(featureId, item);
    }

    @Override
    public void setTitle(CharSequence title) {
        // Handled by framework
    }

    @Override
    public ActionMode startSupportActionMode(ActionMode.Callback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("ActionMode callback can not be null.");
        }

        Context context = getActionBarThemedContext();

        ActionModeWrapper.CallbackWrapper wrappedCallback = new ActionModeWrapper.CallbackWrapper(
                context, callback);
        ActionModeWrapper wrappedMode = null;

        android.view.ActionMode frameworkMode = mActivity.startActionMode(wrappedCallback);

        if (frameworkMode != null) {
            wrappedMode = new ActionModeWrapper(context,
                    mActivity.startActionMode(wrappedCallback));
            wrappedCallback.setLastStartedActionMode(wrappedMode);
        }

        return wrappedMode;
    }

    public void onActionModeStarted(android.view.ActionMode mode) {
        mActivity.onSupportActionModeStarted(
                new ActionModeWrapper(getActionBarThemedContext(), mode));
    }

    @Override
    void setSupportProgressBarVisibility(boolean visible) {
        mActivity.setProgressBarVisibility(visible);
    }

    @Override
    void setSupportProgressBarIndeterminateVisibility(boolean visible) {
        mActivity.setProgressBarIndeterminateVisibility(visible);
    }

    @Override
    void setSupportProgressBarIndeterminate(boolean indeterminate) {
        mActivity.setProgressBarIndeterminate(indeterminate);
    }

    @Override
    void setSupportProgress(int progress) {
        mActivity.setProgress(progress);
    }

    public void onActionModeFinished(android.view.ActionMode mode) {
        mActivity.onSupportActionModeFinished(
                new ActionModeWrapper(getActionBarThemedContext(), mode));
    }

    @Override
    public void supportInvalidateOptionsMenu() {
        mMenu = null;
    }

    @Override
    public boolean onBackPressed() {
        return false;
    }

    @Override
    public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
        // Return null so that ActionBarDrawableToggle uses it's standard impl
        return null;
    }

    class WindowCallbackWrapper implements Window.Callback {
        final Window.Callback mWrapped;

        public WindowCallbackWrapper(Window.Callback wrapped) {
            mWrapped = wrapped;
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            return mWrapped.dispatchKeyEvent(event);
        }

        @Override
        public boolean dispatchKeyShortcutEvent(KeyEvent event) {
            return mWrapped.dispatchKeyShortcutEvent(event);
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            return mWrapped.dispatchTouchEvent(event);
        }

        @Override
        public boolean dispatchTrackballEvent(MotionEvent event) {
            return mWrapped.dispatchTrackballEvent(event);
        }

        public boolean dispatchGenericMotionEvent(MotionEvent event) {
            // This method didn't exist until API 12. Overridden elsewhere.
            return false;
        }

        @Override
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
            return mWrapped.dispatchPopulateAccessibilityEvent(event);
        }

        @Override
        public View onCreatePanelView(int featureId) {
            return mWrapped.onCreatePanelView(featureId);
        }

        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu) {
            return mWrapped.onCreatePanelMenu(featureId, menu);
        }

        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            return mWrapped.onPreparePanel(featureId, view, menu);
        }

        @Override
        public boolean onMenuOpened(int featureId, Menu menu) {
            return mWrapped.onMenuOpened(featureId, menu);
        }

        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            return mWrapped.onMenuItemSelected(featureId, item);
        }

        @Override
        public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
            mWrapped.onWindowAttributesChanged(attrs);
        }

        @Override
        public void onContentChanged() {
            mWrapped.onContentChanged();
        }

        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            mWrapped.onWindowFocusChanged(hasFocus);
        }

        @Override
        public void onAttachedToWindow() {
            mWrapped.onAttachedToWindow();
        }

        @Override
        public void onDetachedFromWindow() {
            mWrapped.onDetachedFromWindow();
        }

        @Override
        public void onPanelClosed(int featureId, Menu menu) {
            mWrapped.onPanelClosed(featureId, menu);
        }

        @Override
        public boolean onSearchRequested() {
            return mWrapped.onSearchRequested();
        }

        @Override
        public android.view.ActionMode onWindowStartingActionMode(
                android.view.ActionMode.Callback callback) {
            return mWrapped.onWindowStartingActionMode(callback);
        }

        /*
         * And here are the money methods, the reason why this wrapper exists:
         */

        @Override
        public void onActionModeStarted(android.view.ActionMode mode) {
            mWrapped.onActionModeStarted(mode);
            ActionBarActivityDelegateHC.this.onActionModeStarted(mode);
        }

        @Override
        public void onActionModeFinished(android.view.ActionMode mode) {
            mWrapped.onActionModeFinished(mode);
            ActionBarActivityDelegateHC.this.onActionModeFinished(mode);
        }
    }
}
