/*
 * 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.sorting;

import android.annotation.StringRes;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;

import com.android.documentsui.R;
import com.android.documentsui.sorting.SortController.WidgetController;
import com.android.documentsui.sorting.SortDimension;
import com.android.documentsui.sorting.SortDimension.SortDirection;
import com.android.documentsui.sorting.SortModel;
import com.android.documentsui.sorting.SortModel.SortDimensionId;
import com.android.documentsui.sorting.SortModel.UpdateListener;
import com.android.documentsui.sorting.SortModel.UpdateType;

/**
 * View controller for the sort widget in grid mode and in small screens.
 */
public final class DropdownSortWidgetController implements WidgetController {

    private static final int LEVEL_UPWARD = 0;
    private static final int LEVEL_DOWNWARD = 10000;

    private final SortModel mModel;
    private final View mWidget;
    private final TextView mDimensionButton;
    private final PopupMenu mMenu;
    private final ImageView mArrow;

    private final OnClickListener mDimensionButtonClickListener = this::showMenu;
    private final OnClickListener mArrowClickListener = this::onChangeDirection;
    private final UpdateListener mUpdateListener = this::onModelUpdate;

    public DropdownSortWidgetController(SortModel model, View widget) {
        mModel = model;
        mWidget = widget;

        mDimensionButton = (TextView) mWidget.findViewById(R.id.sort_dimen_dropdown);
        mMenu = new PopupMenu(widget.getContext(), mDimensionButton, Gravity.END | Gravity.TOP);
        mMenu.setOnMenuItemClickListener(this::onSelectDimension);

        mArrow = (ImageView) mWidget.findViewById(R.id.sort_arrow);

        populateMenuItems();
        onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED);

        mModel.addListener(mUpdateListener);
    }

    @Override
    public void setVisibility(int visibility) {
        mWidget.setVisibility(visibility);
    }

    private void populateMenuItems() {
        Menu menu = mMenu.getMenu();
        menu.clear();
        for (int i = 0; i < mModel.getSize(); ++i) {
            SortDimension dimension = mModel.getDimensionAt(i);
            if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
                menu.add(0, dimension.getId(), Menu.NONE, dimension.getLabelId());
            }
        }
    }

    private void showMenu(View v) {
        mMenu.show();
    }

    private void onModelUpdate(SortModel model, @UpdateType int updateType) {
        final @SortDimensionId int sortedId = model.getSortedDimensionId();

        if ((updateType & SortModel.UPDATE_TYPE_STATUS) != 0) {
            setEnabled(mModel.isSortEnabled());
        }

        if ((updateType & SortModel.UPDATE_TYPE_VISIBILITY) != 0) {
            updateVisibility();
        }

        if ((updateType & SortModel.UPDATE_TYPE_SORTING) != 0) {
            bindSortedDimension(sortedId);
            bindSortDirection(sortedId);
        }
    }

    private void setEnabled(boolean enabled) {
        if (enabled) {
            mDimensionButton.setOnClickListener(mDimensionButtonClickListener);
            mArrow.setOnClickListener(mArrowClickListener);
        } else {
            mMenu.dismiss();
            mDimensionButton.setOnClickListener(null);
            mArrow.setOnClickListener(null);
        }
    }

    private void updateVisibility() {
        Menu menu = mMenu.getMenu();

        for (int i = 0; i < menu.size(); ++i) {
            MenuItem item = menu.getItem(i);
            SortDimension dimension = mModel.getDimensionById(item.getItemId());
            item.setVisible(dimension.getVisibility() == View.VISIBLE);
        }
    }

    private void bindSortedDimension(@SortDimensionId int sortedId) {
        if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
            mDimensionButton.setText(R.string.not_sorted);
        } else {
            SortDimension dimension = mModel.getDimensionById(sortedId);
            mDimensionButton.setText(dimension.getLabelId());
        }
    }

    private void bindSortDirection(@SortDimensionId int sortedId) {
        if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
            mArrow.setVisibility(View.INVISIBLE);
        } else {
            final SortDimension dimension = mModel.getDimensionById(sortedId);
            switch (dimension.getSortDirection()) {
                case SortDimension.SORT_DIRECTION_NONE:
                    mArrow.setVisibility(View.INVISIBLE);
                    break;
                case SortDimension.SORT_DIRECTION_ASCENDING:
                    showArrow(LEVEL_UPWARD, R.string.sort_direction_ascending);
                    break;
                case SortDimension.SORT_DIRECTION_DESCENDING:
                    showArrow(LEVEL_DOWNWARD, R.string.sort_direction_descending);
                    break;
                default:
                    throw new IllegalStateException(
                            "Unknown sort direction: " + dimension.getSortDirection() + ".");
            }
        }
    }

    private void showArrow(int level, @StringRes int descriptionId) {
        mArrow.setVisibility(View.VISIBLE);

        mArrow.getDrawable().mutate();
        mArrow.setImageLevel(level);
        mArrow.setContentDescription(mArrow.getContext().getString(descriptionId));
    }

    private boolean onSelectDimension(MenuItem item) {
        final @SortDirection int preferredDirection = mModel.getCurrentSortDirection();

        final SortDimension dimension = mModel.getDimensionById(item.getItemId());
        final @SortDirection int direction;
        if ((dimension.getSortCapability() & preferredDirection) > 0) {
            direction = preferredDirection;
        } else {
            direction = dimension.getDefaultSortDirection();
        }

        mModel.sortByUser(dimension.getId(), direction);

        return true;
    }

    private void onChangeDirection(View v) {
        final @SortDimensionId int id = mModel.getSortedDimensionId();
        assert(id != SortModel.SORT_DIMENSION_ID_UNKNOWN);

        final SortDimension dimension = mModel.getDimensionById(id);
        mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
    }
}
