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

import static com.android.documentsui.Shared.DEBUG;

import android.annotation.IntDef;
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.View;
import android.widget.Toolbar;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A facade over the various pieces comprising "roots fragment in a Drawer".
 *
 * @see DrawerController#create(DrawerLayout)
 */
abstract class DrawerController implements DrawerListener {
    public static final String TAG = "DrawerController";

    // Drawer opening triggered by tapping the navigation icon
    public static final int OPENED_HAMBURGER = 0;
    // Drawer opening triggered by swiping right from the edge of the screen
    public static final int OPENED_SWIPE = 1;
    // Mostly programmatically forced drawer opening
    public static final int OPENED_OTHER = 2;

    @IntDef(flag = true, value = {
            OPENED_HAMBURGER,
            OPENED_SWIPE,
            OPENED_OTHER
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Trigger {}

    /**
     * Toggles the drawer and sets the OPENED_OTHER as the action that causes opening the drawer.
     * @param open
     */
    abstract void setOpen(boolean open);

    /**
     * Toggles the drawer.
     * @param open
     * @param trigger Indicates what action caused opening the drawer. It is ignored for closing.
     */
    abstract void setOpen(boolean open, @Trigger int trigger);
    abstract boolean isPresent();
    abstract boolean isOpen();
    abstract void setTitle(String title);
    abstract void update();

    /**
     * Returns a controller suitable for {@code Layout}.
     */
    static DrawerController create(Activity activity) {

        DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);

        if (layout == null) {
            return new DummyDrawerController();
        }

        View drawer = activity.findViewById(R.id.drawer_roots);
        Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
        Display.adjustToolbar(toolbar, activity);
        drawer.getLayoutParams().width = calculateDrawerWidth(activity);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                activity,
                layout,
                R.drawable.ic_hamburger,
                R.string.drawer_open,
                R.string.drawer_close);

        return new RuntimeDrawerController(layout, drawer, toggle, toolbar);
    }

    /**
     * Returns a controller suitable for {@code Layout}.
     */
    static DrawerController createDummy() {
        return new DummyDrawerController();
    }

    private static int calculateDrawerWidth(Activity activity) {
        // Material design specification for navigation drawer:
        // https://www.google.com/design/spec/patterns/navigation-drawer.html
        float width = Display.screenWidth(activity) - Display.actionBarHeight(activity);
        float maxWidth = activity.getResources().getDimension(R.dimen.max_drawer_width);
        int finalWidth = (int) ((width > maxWidth ? maxWidth : width));

        if (DEBUG)
            Log.d(TAG, "Calculated drawer width:" + (finalWidth / Display.density(activity)));

        return finalWidth;
    }

    /**
     * Runtime controller that manages a real drawer.
     */
    private static final class RuntimeDrawerController extends DrawerController {
        private final ActionBarDrawerToggle mToggle;
        private DrawerLayout mLayout;
        private View mDrawer;
        private Toolbar mToolbar;
        private @Trigger int mTrigger = OPENED_OTHER;

        public RuntimeDrawerController(
                DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle,
                Toolbar drawerToolbar) {
            mToolbar = drawerToolbar;
            assert(layout != null);

            mLayout = layout;
            mDrawer = drawer;
            mToggle = toggle;

            mLayout.setDrawerListener(this);
        }

        @Override
        void setOpen(boolean open) {
            setOpen(open, OPENED_OTHER);
        }

        @Override
        void setOpen(boolean open, @Trigger int trigger) {
            if (open) {
                mLayout.openDrawer(mDrawer);
                mTrigger = trigger;
            } else {
                mLayout.closeDrawer(mDrawer);
            }
        }

        @Override
        boolean isOpen() {
            return mLayout.isDrawerOpen(mDrawer);
        }

        @Override
        boolean isPresent() {
            return true;
        }

        @Override
        void setTitle(String title) {
            mToolbar.setTitle(title);
        }

        @Override
        void update() {
            mToggle.syncState();
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            mToggle.onDrawerSlide(drawerView, slideOffset);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            mToggle.onDrawerOpened(drawerView);
            Metrics.logDrawerOpened(mToolbar.getContext(), mTrigger);
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            mToggle.onDrawerClosed(drawerView);
            mTrigger = OPENED_OTHER;
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            mToggle.onDrawerStateChanged(newState);
            if (newState == DrawerLayout.STATE_DRAGGING) {
                mTrigger = OPENED_SWIPE;
            }
        }
    }

    /*
     * Dummy controller useful with clients that don't host a real drawer.
     */
    private static final class DummyDrawerController extends DrawerController {

        @Override
        void setOpen(boolean open) {}

        @Override
        void setOpen(boolean open, @Trigger int trigger) {}

        @Override
        boolean isOpen() {
            return false;
        }

        @Override
        boolean isPresent() {
            return false;
        }

        @Override
        void setTitle(String title) {}

        @Override
        void update() {}

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {}

        @Override
        public void onDrawerOpened(View drawerView) {}

        @Override
        public void onDrawerClosed(View drawerView) {}

        @Override
        public void onDrawerStateChanged(int newState) {}
    }
}
