/*
 * Copyright 2015 Hippo Seven
 *
 * 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.hippo.ehviewer.gallery.ui;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.view.MotionEvent;

import com.hippo.ehviewer.gallery.glrenderer.GLCanvas;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.MathUtils;

public class Slider extends GLView {

    private int mStart;
    private int mEnd;
    private int mProgress;
    // 0.0f to 1.0f
    private float mDrawProgress = 0.0f;

    private int m2dp;
    private int m5dp;
    private int m6dp;
    private int m12dp;

    private int mColor = Color.WHITE;

    private OnSetProgressListener mListener;

    public Slider(Context context) {
        m2dp = LayoutUtils.dp2pix(context, 2);
        m5dp = LayoutUtils.dp2pix(context, 5);
        m6dp = LayoutUtils.dp2pix(context, 6);
        m12dp = LayoutUtils.dp2pix(context, 12);

        setMinimumHeight(m12dp);
        setMinimumWidth(512);
    }

    public void setColor(int color) {
        mColor = color;
    }

    public void setRange(int start, int end) {
        mStart = start;
        mEnd = end;
        setProgress(mProgress);
    }

    public void setProgress(int progress) {
        progress = MathUtils.clamp(progress, mStart, mEnd);
        if (mProgress != progress) {
            int oldProgress = mProgress;
            mProgress = progress;
            mDrawProgress = MathUtils.delerp(mStart, mEnd, mProgress);
            if (mListener != null) {
                mListener.onSetProgress(progress, oldProgress, false);
            }
            invalidate();
        }
    }

    public void setOnSetProgressListener(OnSetProgressListener listener) {
        mListener = listener;
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        setMeasuredSize(getMaxSize(getSuggestedMinimumWidth(), widthSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightSpec));
    }

    @Override
    protected void onRender(GLCanvas canvas) {
        super.onRender(canvas);

        int width = getWidth();
        if (width < m12dp * 2) {
            canvas.fillRect(0, 0, width, getHeight(), mColor);
        } else {
            Rect padding = mPaddings;
            int dp6 = m6dp;
            // Draw bar
            canvas.fillRect(padding.left + dp6, padding.top + m5dp,
                    width - dp6 - dp6 - padding.left - padding.right, m2dp, mColor);
            // Draw controllor
            canvas.fillOval(padding.left + dp6 + (width - dp6 - dp6 - padding.left - padding.right) * mDrawProgress,
                    padding.top + dp6, dp6, dp6, mColor);
        }
    }

    @Override
    protected boolean onTouch(MotionEvent event) {

        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                float x = event.getX();
                int progress = Math.round(MathUtils.lerp((float) mStart, (float) mEnd,
                        MathUtils.clamp((x - m6dp) / (getWidth() - m6dp - m6dp), 0.0f, 1.0f)));
                if (progress != mProgress) {
                    mDrawProgress = MathUtils.delerp(mStart, mEnd, progress);
                    invalidate();
                }

                if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                    if (progress != mProgress) {
                        int oldProgress = mProgress;
                        mProgress = progress;
                        if (mListener != null) {
                            mListener.onSetProgress(progress, oldProgress, true);
                        }
                    }
                }

                break;
        }

        return true;
    }

    public interface OnSetProgressListener {

        void onSetProgress(int newProgress, int oldProgress, boolean byUser);
    }
}

@@ -1060,16 +1060,55 @@
  0.0f;%0A%0A
+    private boolean mReverse = false;%0A%0A
     priv
@@ -1117,24 +1117,24 @@
 e int m2dp;%0A
-
     private 
@@ -2215,32 +2215,252 @@
        %7D%0A    %7D%0A%0A
+    public int getProgress() %7B%0A        return mProgress;%0A    %7D%0A%0A    public void setReverse(boolean reverse) %7B%0A        if (mReverse != reverse) %7B%0A            mReverse = reverse;%0A            invalidate();%0A        %7D%0A    %7D%0A%0A
     public void 
@@ -3401,30 +3401,96 @@
 right) *
- mDrawProgress
+%0A                            (mReverse ? (1.0f - mDrawProgress) : mDrawProgress)
 ,%0A      
@@ -3858,16 +3858,90 @@
 CANCEL:%0A
+                Rect padding = mPaddings;%0A                int dp6 = m6dp;%0A
         
@@ -4104,19 +4104,119 @@
 mp((
-x - m6dp) /
+mReverse ? (getWidth() - padding.right - dp6 - x) : (x - dp6 - padding.left)) /%0A                               
  (ge
@@ -4230,19 +4230,48 @@
 ) - 
-m6
+dp6 - 
 dp
+6
  - 
-m6dp
+padding.left - padding.right
 ), 0
@@ -4296,37 +4296,46 @@
             
-if (p
+float oldDrawP
 rogress 
 != mProgress
@@ -4318,36 +4318,39 @@
 rawProgress 
-!
 = m
+Draw
 Progress
 ) %7B%0A        
@@ -4333,32 +4333,26 @@
 DrawProgress
-) %7B%0A    
+;%0A
             
@@ -4405,32 +4405,88 @@
 End, progress);%0A
+                if (mDrawProgress != oldDrawProgress) %7B%0A
                 

Add Slider reverse