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

import android.content.Context;
import android.database.Cursor;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.android.documentsui.Events;
import com.android.documentsui.R;
import com.android.documentsui.State;

public abstract class DocumentHolder
        extends RecyclerView.ViewHolder
        implements View.OnKeyListener {

    public @Nullable String modelId;

    final int mSelectedItemColor;
    final int mDefaultItemColor;
    final boolean mAlwaysShowSummary;
    final Context mContext;

    DocumentHolder.EventListener mEventListener;
    private View.OnKeyListener mKeyListener;
    private View mSelectionHotspot;

    public DocumentHolder(Context context, ViewGroup parent, int layout) {
        this(context, inflateLayout(context, parent, layout));
    }

    public DocumentHolder(Context context, View item) {
        super(item);

        itemView.setOnKeyListener(this);

        mContext = context;

        mDefaultItemColor = context.getColor(R.color.item_doc_background);
        mSelectedItemColor = context.getColor(R.color.item_doc_background_selected);
        mAlwaysShowSummary = context.getResources().getBoolean(R.bool.always_show_summary);

        mSelectionHotspot = itemView.findViewById(R.id.icon_check);
    }

    /**
     * Binds the view to the given item data.
     * @param cursor
     * @param modelId
     * @param state
     */
    public abstract void bind(Cursor cursor, String modelId, State state);

    /**
     * Makes the associated item view appear selected. Note that this merely affects the appearance
     * of the view, it doesn't actually select the item.
     *
     * @param selected
     */
    public void setSelected(boolean selected) {
        itemView.setActivated(selected);
        itemView.setBackgroundColor(selected ? mSelectedItemColor : mDefaultItemColor);
    }

    /**
     * Highlights the associated item view.
     * @param highlighted
     */
    public void setHighlighted(boolean highlighted) {
        itemView.setBackgroundColor(highlighted ? mSelectedItemColor : mDefaultItemColor);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        // Event listener should always be set.
        assert(mEventListener != null);

        return mEventListener.onKey(this,  keyCode,  event);
    }

    public void addEventListener(DocumentHolder.EventListener listener) {
        // Just handle one for now; switch to a list if necessary.
        assert(mEventListener == null);
        mEventListener = listener;
    }

    public void addOnKeyListener(View.OnKeyListener listener) {
        // Just handle one for now; switch to a list if necessary.
        assert(mKeyListener == null);
        mKeyListener = listener;
    }

    public void setEnabled(boolean enabled) {
        setEnabledRecursive(itemView, enabled);
    }

    public boolean onSingleTapUp(MotionEvent event) {
        if (Events.isMouseEvent(event)) {
            // Mouse clicks select.
            // TODO:  && input.isPrimaryButtonPressed(), but it is returning false.
            if (mEventListener != null) {
                return mEventListener.onSelect(this);
            }
        } else if (Events.isTouchEvent(event)) {
            // Touch events select if they occur in the selection hotspot, otherwise they activate.
            if (mEventListener == null) {
                return false;
            }

            // Do everything in global coordinates - it makes things simpler.
            Rect rect = new Rect();
            mSelectionHotspot.getGlobalVisibleRect(rect);

            // If the tap occurred within the icon rect, consider it a selection.
            if (rect.contains((int)event.getRawX(), (int)event.getRawY())) {
                return mEventListener.onSelect(this);
            } else {
                return mEventListener.onActivate(this);
            }
        }
        return false;
    }

    static void setEnabledRecursive(View itemView, boolean enabled) {
        if (itemView == null) return;
        if (itemView.isEnabled() == enabled) return;
        itemView.setEnabled(enabled);

        if (itemView instanceof ViewGroup) {
            final ViewGroup vg = (ViewGroup) itemView;
            for (int i = vg.getChildCount() - 1; i >= 0; i--) {
                setEnabledRecursive(vg.getChildAt(i), enabled);
            }
        }
    }

    private static View inflateLayout(Context context, ViewGroup parent, int layout) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        return inflater.inflate(layout, parent, false);
    }

    /**
     * Implement this in order to be able to respond to events coming from DocumentHolders.
     */
    interface EventListener {
        /**
         * Handles activation events on the document holder.
         *
         * @param doc The target DocumentHolder
         * @return Whether the event was handled.
         */
        public boolean onActivate(DocumentHolder doc);

        /**
         * Handles selection events on the document holder.
         *
         * @param doc The target DocumentHolder
         * @return Whether the event was handled.
         */
        public boolean onSelect(DocumentHolder doc);

        /**
         * Handles key events on the document holder.
         *
         * @param doc The target DocumentHolder.
         * @param keyCode Key code for the event.
         * @param event KeyEvent for the event.
         * @return Whether the event was handled.
         */
        public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event);
    }
}
