/*
 * Copyright (C) 2016 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 android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.android.documentsui.Shared.DEBUG;

import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;

/**
 * A facade over the portions of the app and drawer toolbars.
 */
class NavigationView {

    private static final String TAG = "NavigationView";

    private final DrawerController mDrawer;
    private final DocumentsToolbar mToolbar;
    private final Spinner mBreadcrumb;
    private final State mState;
    private final NavigationView.Environment mEnv;
    private final BreadcrumbAdapter mBreadcrumbAdapter;

    private boolean mIgnoreNextNavigation;

    public NavigationView(
            DrawerController drawer,
            DocumentsToolbar toolbar,
            Spinner breadcrumb,
            State state,
            NavigationView.Environment env) {

        mToolbar = toolbar;
        mBreadcrumb = breadcrumb;
        mDrawer = drawer;
        mState = state;
        mEnv = env;

        mBreadcrumbAdapter = new BreadcrumbAdapter(mState, mEnv);
        mToolbar.setNavigationOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onNavigationIconClicked();
                    }

                });

        mBreadcrumb.setOnItemSelectedListener(
                new OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(
                            AdapterView<?> parent, View view, int position, long id) {
                        onBreadcrumbItemSelected(position);
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {}
                });

    }

    private void onNavigationIconClicked() {
        if (mDrawer.isPresent()) {
            mDrawer.setOpen(true);
        }
    }

    private void onBreadcrumbItemSelected(int position) {
        if (mIgnoreNextNavigation) {
            mIgnoreNextNavigation = false;
            return;
        }

        while (mState.stack.size() > position + 1) {
            mState.popDocument();
        }
        mEnv.refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE);
    }

    void update() {

        // TODO: Looks to me like this block is never getting hit.
        if (mEnv.isSearchExpanded()) {
            mToolbar.setTitle(null);
            mBreadcrumb.setVisibility(View.GONE);
            mBreadcrumb.setAdapter(null);
            return;
        }

        mDrawer.setTitle(mEnv.getDrawerTitle());

        mToolbar.setNavigationIcon(getActionBarIcon());
        mToolbar.setNavigationContentDescription(R.string.drawer_open);

        if (mState.stack.size() <= 1) {
            showBreadcrumb(false);
            String title = mEnv.getCurrentRoot().title;
            if (DEBUG) Log.d(TAG, "New toolbar title is: " + title);
            mToolbar.setTitle(title);
        } else {
            showBreadcrumb(true);
            mToolbar.setTitle(null);
            mIgnoreNextNavigation = true;
            mBreadcrumb.setSelection(mBreadcrumbAdapter.getCount() - 1, false);
        }

        if (DEBUG) Log.d(TAG, "Final toolbar title is: " + mToolbar.getTitle());
    }

    private void showBreadcrumb(boolean visibility) {
        if (visibility) {
            mBreadcrumb.setVisibility(VISIBLE);
            mBreadcrumb.setAdapter(mBreadcrumbAdapter);
        } else {
            mBreadcrumb.setVisibility(GONE);
            mBreadcrumb.setAdapter(null);
        }
    }

    // Hamburger if drawer is present, else root icon, or sad nullness.
    private @Nullable Drawable getActionBarIcon() {
        if (mDrawer.isPresent()) {
            return mToolbar.getContext().getDrawable(R.drawable.ic_hamburger);
        } else {
            RootInfo root = mEnv.getCurrentRoot();
            if (root != null) {
                return root.loadToolbarIcon(mToolbar.getContext());
            }
        }
        return null;
    }

    void revealRootsDrawer(boolean open) {
        mDrawer.setOpen(open);
    }

    /**
     * Class providing toolbar with runtime access to useful activity data.
     */
    static final class BreadcrumbAdapter extends BaseAdapter {

        private Environment mEnv;
        private State mState;

        public BreadcrumbAdapter(State state, Environment env) {
            mState = state;
            mEnv = env;
        }

        @Override
        public int getCount() {
            return mState.stack.size();
        }

        @Override
        public DocumentInfo getItem(int position) {
            return mState.stack.get(mState.stack.size() - position - 1);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_subdir_title, parent, false);
            }

            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
            final DocumentInfo doc = getItem(position);

            if (position == 0) {
                final RootInfo root = mEnv.getCurrentRoot();
                title.setText(root.title);
            } else {
                title.setText(doc.displayName);
            }

            return convertView;
        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_subdir, parent, false);
            }

            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
            final DocumentInfo doc = getItem(position);

            if (position == 0) {
                final RootInfo root = mEnv.getCurrentRoot();
                title.setText(root.title);
            } else {
                title.setText(doc.displayName);
            }

            return convertView;
        }
    }

    interface Environment {
        RootInfo getCurrentRoot();
        String getDrawerTitle();
        void refreshCurrentRootAndDirectory(int animation);
        boolean isSearchExpanded();
    }
}
