/*
 * 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 com.android.gallery3d.filtershow.state;

import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.LinearLayout;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.imageshow.MasterImage;

public class StatePanelTrack extends LinearLayout implements PanelTrack {

    private static final String LOGTAG = "StatePanelTrack";
    private Point mTouchPoint;
    private StateView mCurrentView;
    private StateView mCurrentSelectedView;
    private boolean mExited = false;
    private boolean mStartedDrag = false;
    private StateAdapter mAdapter;
    private DragListener mDragListener = new DragListener(this);
    private float mDeleteSlope = 0.2f;
    private GestureDetector mGestureDetector;
    private int mElemWidth;
    private int mElemHeight;
    private int mElemSize;
    private int mElemEndSize;
    private int mEndElemWidth;
    private int mEndElemHeight;
    private long mTouchTime;
    private int mMaxTouchDelay = 300; // 300ms delay for touch
    private static final boolean ALLOWS_DRAG = false;
    private DataSetObserver mObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            fillContent(false);
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            fillContent(false);
        }
    };

    public StatePanelTrack(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StatePanelTrack);
        mElemSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemSize, 0);
        mElemEndSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemEndSize, 0);
        if (getOrientation() == LinearLayout.HORIZONTAL) {
            mElemWidth = mElemSize;
            mElemHeight = LayoutParams.MATCH_PARENT;
            mEndElemWidth = mElemEndSize;
            mEndElemHeight = LayoutParams.MATCH_PARENT;
        } else {
            mElemWidth = LayoutParams.MATCH_PARENT;
            mElemHeight = mElemSize;
            mEndElemWidth = LayoutParams.MATCH_PARENT;
            mEndElemHeight = mElemEndSize;
        }
        GestureDetector.SimpleOnGestureListener simpleOnGestureListener
                = new GestureDetector.SimpleOnGestureListener(){
            @Override
            public void onLongPress(MotionEvent e) {
                longPress(e);
            }
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                addDuplicate(e);
                return true;
            }
        };
        mGestureDetector = new GestureDetector(context, simpleOnGestureListener);
    }

    private void addDuplicate(MotionEvent e) {
        if (mCurrentSelectedView == null) {
            return;
        }
        int pos = findChild(mCurrentSelectedView);
        if (pos != -1) {
            mAdapter.insert(new State(mCurrentSelectedView.getState()), pos);
            fillContent(true);
        }
    }

    private void longPress(MotionEvent e) {
        View view = findChildAt((int) e.getX(), (int) e.getY());
        if (view == null) {
            return;
        }
        if (view instanceof StateView) {
            StateView stateView = (StateView) view;
            stateView.setDuplicateButton(true);
        }
    }

    public void setAdapter(StateAdapter adapter) {
        mAdapter = adapter;
        mAdapter.registerDataSetObserver(mObserver);
        mAdapter.setOrientation(getOrientation());
        fillContent(false);
        requestLayout();
    }

    public StateView findChildWithState(State state) {
        for (int i = 0; i < getChildCount(); i++) {
            StateView view = (StateView) getChildAt(i);
            if (view.getState() == state) {
                return view;
            }
        }
        return null;
    }

    public void fillContent(boolean animate) {
        if (!animate) {
            this.setLayoutTransition(null);
        }
        int n = mAdapter.getCount();
        for (int i = 0; i < getChildCount(); i++) {
            StateView child = (StateView) getChildAt(i);
            child.resetPosition();
            if (!mAdapter.contains(child.getState())) {
                removeView(child);
            }
        }
        LayoutParams params = new LayoutParams(mElemWidth, mElemHeight);
        for (int i = 0; i < n; i++) {
            State s = mAdapter.getItem(i);
            if (findChildWithState(s) == null) {
                View view = mAdapter.getView(i, null, this);
                addView(view, i, params);
            }
        }

        for (int i = 0; i < n; i++) {
            State state = mAdapter.getItem(i);
            StateView view = (StateView) getChildAt(i);
            view.setState(state);
            if (i == 0) {
                view.setType(StateView.BEGIN);
            } else if (i == n - 1) {
                view.setType(StateView.END);
            } else {
                view.setType(StateView.DEFAULT);
            }
            view.resetPosition();
        }

        if (!animate) {
            this.setLayoutTransition(new LayoutTransition());
        }
    }

    public void onTouch(MotionEvent event, StateView view) {
        if (!view.isDraggable()) {
            return;
        }
        mCurrentView = view;
        if (mCurrentSelectedView == mCurrentView) {
            return;
        }
        if (mCurrentSelectedView != null) {
            mCurrentSelectedView.setSelected(false);
        }
        // We changed the current view -- let's reset the
        // gesture detector.
        MotionEvent cancelEvent = MotionEvent.obtain(event);
        cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
        mGestureDetector.onTouchEvent(cancelEvent);
        mCurrentSelectedView = mCurrentView;
        // We have to send the event to the gesture detector
        mGestureDetector.onTouchEvent(event);
        mTouchTime = System.currentTimeMillis();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (mCurrentView != null) {
            return true;
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mCurrentView == null) {
            return false;
        }
        if (mTouchTime == 0) {
            mTouchTime = System.currentTimeMillis();
        }
        mGestureDetector.onTouchEvent(event);
        if (mTouchPoint == null) {
            mTouchPoint = new Point();
            mTouchPoint.x = (int) event.getX();
            mTouchPoint.y = (int) event.getY();
        }

        if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
            float translation = event.getY() - mTouchPoint.y;
            float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight());
            if (getOrientation() == LinearLayout.VERTICAL) {
                translation = event.getX() - mTouchPoint.x;
                alpha = 1.0f - (Math.abs(translation) / mCurrentView.getWidth());
                mCurrentView.setTranslationX(translation);
            } else {
                mCurrentView.setTranslationY(translation);
            }
            mCurrentView.setBackgroundAlpha(alpha);
            if (ALLOWS_DRAG && alpha < 0.7) {
                setOnDragListener(mDragListener);
                DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView);
                mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0);
                mStartedDrag = true;
            }
        }
        if (!mExited && mCurrentView != null
                && mCurrentView.getBackgroundAlpha() > mDeleteSlope
                && event.getActionMasked() == MotionEvent.ACTION_UP
                && System.currentTimeMillis() - mTouchTime < mMaxTouchDelay) {
            FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
            mCurrentView.setSelected(true);
            if (representation != MasterImage.getImage().getCurrentFilterRepresentation()) {
                FilterShowActivity activity = (FilterShowActivity) getContext();
                activity.showRepresentation(representation);
                mCurrentView.setSelected(false);
            }
        }
        if (event.getActionMasked() == MotionEvent.ACTION_UP
                || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
            checkEndState();
            if (mCurrentView != null) {
                FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
                if (representation.getEditorId() == ImageOnlyEditor.ID) {
                    mCurrentView.setSelected(false);
                }
            }
        }
        return true;
    }

    public void checkEndState() {
        mTouchPoint = null;
        mTouchTime = 0;
        if (mExited || mCurrentView.getBackgroundAlpha() < mDeleteSlope) {
            int origin = findChild(mCurrentView);
            if (origin != -1) {
                State current = mAdapter.getItem(origin);
                FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation();
                FilterRepresentation removedRep = current.getFilterRepresentation();
                mAdapter.remove(current);
                fillContent(true);
                if (currentRep != null && removedRep != null
                        && currentRep.getFilterClass() == removedRep.getFilterClass()) {
                    FilterShowActivity activity = (FilterShowActivity) getContext();
                    activity.backToMain();
                    return;
                }
            }
        } else {
            mCurrentView.setBackgroundAlpha(1.0f);
            mCurrentView.setTranslationX(0);
            mCurrentView.setTranslationY(0);
        }
        if (mCurrentSelectedView != null) {
            mCurrentSelectedView.invalidate();
        }
        if (mCurrentView != null) {
            mCurrentView.invalidate();
        }
        mCurrentView = null;
        mExited = false;
        mStartedDrag = false;
    }

    public View findChildAt(int x, int y) {
        Rect frame = new Rect();
        int scrolledXInt = getScrollX() + x;
        int scrolledYInt = getScrollY() + y;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.getHitRect(frame);
            if (frame.contains(scrolledXInt, scrolledYInt)) {
                return child;
            }
        }
        return null;
    }

    public int findChild(View view) {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child == view) {
                return i;
            }
        }
        return -1;
    }

    public StateView getCurrentView() {
        return mCurrentView;
    }

    public void setCurrentView(View currentView) {
        mCurrentView = (StateView) currentView;
    }

    public void setExited(boolean value) {
        mExited = value;
    }

    public Point getTouchPoint() {
        return mTouchPoint;
    }

    public Adapter getAdapter() {
        return mAdapter;
    }
}
