/*
 * Copyright (C) 2011 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.settings.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.DynamicLayout;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;

import com.android.internal.util.Preconditions;
import com.android.settings.R;

/**
 * Sweep across a {@link ChartView} at a specific {@link ChartAxis} value, which
 * a user can drag.
 */
public class ChartSweepView extends View {

    private static final boolean DRAW_OUTLINE = false;

    // TODO: clean up all the various padding/offset/margins

    private Drawable mSweep;
    private Rect mSweepPadding = new Rect();

    /** Offset of content inside this view. */
    private Rect mContentOffset = new Rect();
    /** Offset of {@link #mSweep} inside this view. */
    private Point mSweepOffset = new Point();

    private Rect mMargins = new Rect();
    private float mNeighborMargin;
    private int mSafeRegion;

    private int mFollowAxis;

    private int mLabelMinSize;
    private float mLabelSize;

    private int mLabelTemplateRes;
    private int mLabelColor;

    private SpannableStringBuilder mLabelTemplate;
    private DynamicLayout mLabelLayout;

    private ChartAxis mAxis;
    private long mValue;
    private long mLabelValue;

    private long mValidAfter;
    private long mValidBefore;
    private ChartSweepView mValidAfterDynamic;
    private ChartSweepView mValidBeforeDynamic;

    private float mLabelOffset;

    private Paint mOutlinePaint = new Paint();

    public static final int HORIZONTAL = 0;
    public static final int VERTICAL = 1;

    private int mTouchMode = MODE_NONE;

    private static final int MODE_NONE = 0;
    private static final int MODE_DRAG = 1;
    private static final int MODE_LABEL = 2;

    private static final int LARGE_WIDTH = 1024;

    private long mDragInterval = 1;

    public interface OnSweepListener {
        public void onSweep(ChartSweepView sweep, boolean sweepDone);
        public void requestEdit(ChartSweepView sweep);
    }

    private OnSweepListener mListener;

    private float mTrackingStart;
    private MotionEvent mTracking;

    private ChartSweepView[] mNeighbors = new ChartSweepView[0];

    public ChartSweepView(Context context) {
        this(context, null);
    }

    public ChartSweepView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ChartSweepView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.ChartSweepView, defStyle, 0);

        setSweepDrawable(a.getDrawable(R.styleable.ChartSweepView_sweepDrawable));
        setFollowAxis(a.getInt(R.styleable.ChartSweepView_followAxis, -1));
        setNeighborMargin(a.getDimensionPixelSize(R.styleable.ChartSweepView_neighborMargin, 0));
        setSafeRegion(a.getDimensionPixelSize(R.styleable.ChartSweepView_safeRegion, 0));

        setLabelMinSize(a.getDimensionPixelSize(R.styleable.ChartSweepView_labelSize, 0));
        setLabelTemplate(a.getResourceId(R.styleable.ChartSweepView_labelTemplate, 0));
        setLabelColor(a.getColor(R.styleable.ChartSweepView_labelColor, Color.BLUE));

        // TODO: moved focused state directly into assets
        setBackgroundResource(R.drawable.data_usage_sweep_background);

        mOutlinePaint.setColor(Color.RED);
        mOutlinePaint.setStrokeWidth(1f);
        mOutlinePaint.setStyle(Style.STROKE);

        a.recycle();

        setClickable(true);
        setFocusable(true);
        setOnClickListener(mClickListener);

        setWillNotDraw(false);
    }

    private OnClickListener mClickListener = new OnClickListener() {
        public void onClick(View v) {
            dispatchRequestEdit();
        }
    };

    void init(ChartAxis axis) {
        mAxis = Preconditions.checkNotNull(axis, "missing axis");
    }

    public void setNeighbors(ChartSweepView... neighbors) {
        mNeighbors = neighbors;
    }

    public int getFollowAxis() {
        return mFollowAxis;
    }

    public Rect getMargins() {
        return mMargins;
    }

    public void setDragInterval(long dragInterval) {
        mDragInterval = dragInterval;
    }

    /**
     * Return the number of pixels that the "target" area is inset from the
     * {@link View} edge, along the current {@link #setFollowAxis(int)}.
     */
    private float getTargetInset() {
        if (mFollowAxis == VERTICAL) {
            final float targetHeight = mSweep.getIntrinsicHeight() - mSweepPadding.top
                    - mSweepPadding.bottom;
            return mSweepPadding.top + (targetHeight / 2) + mSweepOffset.y;
        } else {
            final float targetWidth = mSweep.getIntrinsicWidth() - mSweepPadding.left
                    - mSweepPadding.right;
            return mSweepPadding.left + (targetWidth / 2) + mSweepOffset.x;
        }
    }

    public void addOnSweepListener(OnSweepListener listener) {
        mListener = listener;
    }

    private void dispatchOnSweep(boolean sweepDone) {
        if (mListener != null) {
            mListener.onSweep(this, sweepDone);
        }
    }

    private void dispatchRequestEdit() {
        if (mListener != null) {
            mListener.requestEdit(this);
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        setFocusable(enabled);
        requestLayout();
    }

    public void setSweepDrawable(Drawable sweep) {
        if (mSweep != null) {
            mSweep.setCallback(null);
            unscheduleDrawable(mSweep);
        }

        if (sweep != null) {
            sweep.setCallback(this);
            if (sweep.isStateful()) {
                sweep.setState(getDrawableState());
            }
            sweep.setVisible(getVisibility() == VISIBLE, false);
            mSweep = sweep;
            sweep.getPadding(mSweepPadding);
        } else {
            mSweep = null;
        }

        invalidate();
    }

    public void setFollowAxis(int followAxis) {
        mFollowAxis = followAxis;
    }

    public void setLabelMinSize(int minSize) {
        mLabelMinSize = minSize;
        invalidateLabelTemplate();
    }

    public void setLabelTemplate(int resId) {
        mLabelTemplateRes = resId;
        invalidateLabelTemplate();
    }

    public void setLabelColor(int color) {
        mLabelColor = color;
        invalidateLabelTemplate();
    }

    private void invalidateLabelTemplate() {
        if (mLabelTemplateRes != 0) {
            final CharSequence template = getResources().getText(mLabelTemplateRes);

            final TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            paint.density = getResources().getDisplayMetrics().density;
            paint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale);
            paint.setColor(mLabelColor);

            mLabelTemplate = new SpannableStringBuilder(template);
            mLabelLayout = new DynamicLayout(
                    mLabelTemplate, paint, LARGE_WIDTH, Alignment.ALIGN_RIGHT, 1f, 0f, false);
            invalidateLabel();

        } else {
            mLabelTemplate = null;
            mLabelLayout = null;
        }

        invalidate();
        requestLayout();
    }

    private void invalidateLabel() {
        if (mLabelTemplate != null && mAxis != null) {
            mLabelValue = mAxis.buildLabel(getResources(), mLabelTemplate, mValue);
            setContentDescription(mLabelTemplate);
            invalidateLabelOffset();
            invalidate();
        } else {
            mLabelValue = mValue;
        }
    }

    /**
     * When overlapping with neighbor, split difference and push label.
     */
    public void invalidateLabelOffset() {
        float margin;
        float labelOffset = 0;
        if (mFollowAxis == VERTICAL) {
            if (mValidAfterDynamic != null) {
                mLabelSize = Math.max(getLabelWidth(this), getLabelWidth(mValidAfterDynamic));
                margin = getLabelTop(mValidAfterDynamic) - getLabelBottom(this);
                if (margin < 0) {
                    labelOffset = margin / 2;
                }
            } else if (mValidBeforeDynamic != null) {
                mLabelSize = Math.max(getLabelWidth(this), getLabelWidth(mValidBeforeDynamic));
                margin = getLabelTop(this) - getLabelBottom(mValidBeforeDynamic);
                if (margin < 0) {
                    labelOffset = -margin / 2;
                }
            } else {
                mLabelSize = getLabelWidth(this);
            }
        } else {
            // TODO: implement horizontal labels
        }

        mLabelSize = Math.max(mLabelSize, mLabelMinSize);

        // when offsetting label, neighbor probably needs to offset too
        if (labelOffset != mLabelOffset) {
            mLabelOffset = labelOffset;
            invalidate();
            if (mValidAfterDynamic != null) mValidAfterDynamic.invalidateLabelOffset();
            if (mValidBeforeDynamic != null) mValidBeforeDynamic.invalidateLabelOffset();
        }
    }

    @Override
    public void jumpDrawablesToCurrentState() {
        super.jumpDrawablesToCurrentState();
        if (mSweep != null) {
            mSweep.jumpToCurrentState();
        }
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (mSweep != null) {
            mSweep.setVisible(visibility == VISIBLE, false);
        }
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return who == mSweep || super.verifyDrawable(who);
    }

    public ChartAxis getAxis() {
        return mAxis;
    }

    public void setValue(long value) {
        mValue = value;
        invalidateLabel();
    }

    public long getValue() {
        return mValue;
    }

    public long getLabelValue() {
        return mLabelValue;
    }

    public float getPoint() {
        if (isEnabled()) {
            return mAxis.convertToPoint(mValue);
        } else {
            // when disabled, show along top edge
            return 0;
        }
    }

    /**
     * Set valid range this sweep can move within, in {@link #mAxis} values. The
     * most restrictive combination of all valid ranges is used.
     */
    public void setValidRange(long validAfter, long validBefore) {
        mValidAfter = validAfter;
        mValidBefore = validBefore;
    }

    public void setNeighborMargin(float neighborMargin) {
        mNeighborMargin = neighborMargin;
    }

    public void setSafeRegion(int safeRegion) {
        mSafeRegion = safeRegion;
    }

    /**
     * Set valid range this sweep can move within, defined by the given
     * {@link ChartSweepView}. The most restrictive combination of all valid
     * ranges is used.
     */
    public void setValidRangeDynamic(ChartSweepView validAfter, ChartSweepView validBefore) {
        mValidAfterDynamic = validAfter;
        mValidBeforeDynamic = validBefore;
    }

    /**
     * Test if given {@link MotionEvent} is closer to another
     * {@link ChartSweepView} compared to ourselves.
     */
    public boolean isTouchCloserTo(MotionEvent eventInParent, ChartSweepView another) {
        final float selfDist = getTouchDistanceFromTarget(eventInParent);
        final float anotherDist = another.getTouchDistanceFromTarget(eventInParent);
        return anotherDist < selfDist;
    }

    private float getTouchDistanceFromTarget(MotionEvent eventInParent) {
        if (mFollowAxis == HORIZONTAL) {
            return Math.abs(eventInParent.getX() - (getX() + getTargetInset()));
        } else {
            return Math.abs(eventInParent.getY() - (getY() + getTargetInset()));
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) return false;

        final View parent = (View) getParent();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {

                // only start tracking when in sweet spot
                final boolean acceptDrag;
                final boolean acceptLabel;
                if (mFollowAxis == VERTICAL) {
                    acceptDrag = event.getX() > getWidth() - (mSweepPadding.right * 8);
                    acceptLabel = mLabelLayout != null ? event.getX() < mLabelLayout.getWidth()
                            : false;
                } else {
                    acceptDrag = event.getY() > getHeight() - (mSweepPadding.bottom * 8);
                    acceptLabel = mLabelLayout != null ? event.getY() < mLabelLayout.getHeight()
                            : false;
                }

                final MotionEvent eventInParent = event.copy();
                eventInParent.offsetLocation(getLeft(), getTop());

                // ignore event when closer to a neighbor
                for (ChartSweepView neighbor : mNeighbors) {
                    if (isTouchCloserTo(eventInParent, neighbor)) {
                        return false;
                    }
                }

                if (acceptDrag) {
                    if (mFollowAxis == VERTICAL) {
                        mTrackingStart = getTop() - mMargins.top;
                    } else {
                        mTrackingStart = getLeft() - mMargins.left;
                    }
                    mTracking = event.copy();
                    mTouchMode = MODE_DRAG;

                    // starting drag should activate entire chart
                    if (!parent.isActivated()) {
                        parent.setActivated(true);
                    }

                    return true;
                } else if (acceptLabel) {
                    mTouchMode = MODE_LABEL;
                    return true;
                } else {
                    mTouchMode = MODE_NONE;
                    return false;
                }
            }
            case MotionEvent.ACTION_MOVE: {
                if (mTouchMode == MODE_LABEL) {
                    return true;
                }

                getParent().requestDisallowInterceptTouchEvent(true);

                // content area of parent
                final Rect parentContent = getParentContentRect();
                final Rect clampRect = computeClampRect(parentContent);
                if (clampRect.isEmpty()) return true;

                long value;
                if (mFollowAxis == VERTICAL) {
                    final float currentTargetY = getTop() - mMargins.top;
                    final float requestedTargetY = mTrackingStart
                            + (event.getRawY() - mTracking.getRawY());
                    final float clampedTargetY = MathUtils.constrain(
                            requestedTargetY, clampRect.top, clampRect.bottom);
                    setTranslationY(clampedTargetY - currentTargetY);

                    value = mAxis.convertToValue(clampedTargetY - parentContent.top);
                } else {
                    final float currentTargetX = getLeft() - mMargins.left;
                    final float requestedTargetX = mTrackingStart
                            + (event.getRawX() - mTracking.getRawX());
                    final float clampedTargetX = MathUtils.constrain(
                            requestedTargetX, clampRect.left, clampRect.right);
                    setTranslationX(clampedTargetX - currentTargetX);

                    value = mAxis.convertToValue(clampedTargetX - parentContent.left);
                }

                // round value from drag to nearest increment
                value -= value % mDragInterval;
                setValue(value);

                dispatchOnSweep(false);
                return true;
            }
            case MotionEvent.ACTION_UP: {
                if (mTouchMode == MODE_LABEL) {
                    performClick();
                } else if (mTouchMode == MODE_DRAG) {
                    mTrackingStart = 0;
                    mTracking = null;
                    mValue = mLabelValue;
                    dispatchOnSweep(true);
                    setTranslationX(0);
                    setTranslationY(0);
                    requestLayout();
                }

                mTouchMode = MODE_NONE;
                return true;
            }
            default: {
                return false;
            }
        }
    }

    /**
     * Update {@link #mValue} based on current position, including any
     * {@link #onTouchEvent(MotionEvent)} in progress. Typically used when
     * {@link ChartAxis} changes during sweep adjustment.
     */
    public void updateValueFromPosition() {
        final Rect parentContent = getParentContentRect();
        if (mFollowAxis == VERTICAL) {
            final float effectiveY = getY() - mMargins.top - parentContent.top;
            setValue(mAxis.convertToValue(effectiveY));
        } else {
            final float effectiveX = getX() - mMargins.left - parentContent.left;
            setValue(mAxis.convertToValue(effectiveX));
        }
    }

    public int shouldAdjustAxis() {
        return mAxis.shouldAdjustAxis(getValue());
    }

    private Rect getParentContentRect() {
        final View parent = (View) getParent();
        return new Rect(parent.getPaddingLeft(), parent.getPaddingTop(),
                parent.getWidth() - parent.getPaddingRight(),
                parent.getHeight() - parent.getPaddingBottom());
    }

    @Override
    public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
        // ignored to keep LayoutTransition from animating us
    }

    @Override
    public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
        // ignored to keep LayoutTransition from animating us
    }

    private long getValidAfterDynamic() {
        final ChartSweepView dynamic = mValidAfterDynamic;
        return dynamic != null && dynamic.isEnabled() ? dynamic.getValue() : Long.MIN_VALUE;
    }

    private long getValidBeforeDynamic() {
        final ChartSweepView dynamic = mValidBeforeDynamic;
        return dynamic != null && dynamic.isEnabled() ? dynamic.getValue() : Long.MAX_VALUE;
    }

    /**
     * Compute {@link Rect} in {@link #getParent()} coordinates that we should
     * be clamped inside of, usually from {@link #setValidRange(long, long)}
     * style rules.
     */
    private Rect computeClampRect(Rect parentContent) {
        // create two rectangles, and pick most restrictive combination
        final Rect rect = buildClampRect(parentContent, mValidAfter, mValidBefore, 0f);
        final Rect dynamicRect = buildClampRect(
                parentContent, getValidAfterDynamic(), getValidBeforeDynamic(), mNeighborMargin);

        if (!rect.intersect(dynamicRect)) {
            rect.setEmpty();
        }
        return rect;
    }

    private Rect buildClampRect(
            Rect parentContent, long afterValue, long beforeValue, float margin) {
        if (mAxis instanceof InvertedChartAxis) {
            long temp = beforeValue;
            beforeValue = afterValue;
            afterValue = temp;
        }

        final boolean afterValid = afterValue != Long.MIN_VALUE && afterValue != Long.MAX_VALUE;
        final boolean beforeValid = beforeValue != Long.MIN_VALUE && beforeValue != Long.MAX_VALUE;

        final float afterPoint = mAxis.convertToPoint(afterValue) + margin;
        final float beforePoint = mAxis.convertToPoint(beforeValue) - margin;

        final Rect clampRect = new Rect(parentContent);
        if (mFollowAxis == VERTICAL) {
            if (beforeValid) clampRect.bottom = clampRect.top + (int) beforePoint;
            if (afterValid) clampRect.top += afterPoint;
        } else {
            if (beforeValid) clampRect.right = clampRect.left + (int) beforePoint;
            if (afterValid) clampRect.left += afterPoint;
        }
        return clampRect;
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (mSweep.isStateful()) {
            mSweep.setState(getDrawableState());
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        // TODO: handle vertical labels
        if (isEnabled() && mLabelLayout != null) {
            final int sweepHeight = mSweep.getIntrinsicHeight();
            final int templateHeight = mLabelLayout.getHeight();

            mSweepOffset.x = 0;
            mSweepOffset.y = 0;
            mSweepOffset.y = (int) ((templateHeight / 2) - getTargetInset());
            setMeasuredDimension(mSweep.getIntrinsicWidth(), Math.max(sweepHeight, templateHeight));

        } else {
            mSweepOffset.x = 0;
            mSweepOffset.y = 0;
            setMeasuredDimension(mSweep.getIntrinsicWidth(), mSweep.getIntrinsicHeight());
        }

        if (mFollowAxis == VERTICAL) {
            final int targetHeight = mSweep.getIntrinsicHeight() - mSweepPadding.top
                    - mSweepPadding.bottom;
            mMargins.top = -(mSweepPadding.top + (targetHeight / 2));
            mMargins.bottom = 0;
            mMargins.left = -mSweepPadding.left;
            mMargins.right = mSweepPadding.right;
        } else {
            final int targetWidth = mSweep.getIntrinsicWidth() - mSweepPadding.left
                    - mSweepPadding.right;
            mMargins.left = -(mSweepPadding.left + (targetWidth / 2));
            mMargins.right = 0;
            mMargins.top = -mSweepPadding.top;
            mMargins.bottom = mSweepPadding.bottom;
        }

        mContentOffset.set(0, 0, 0, 0);

        // make touch target area larger
        final int widthBefore = getMeasuredWidth();
        final int heightBefore = getMeasuredHeight();
        if (mFollowAxis == HORIZONTAL) {
            final int widthAfter = widthBefore * 3;
            setMeasuredDimension(widthAfter, heightBefore);
            mContentOffset.left = (widthAfter - widthBefore) / 2;

            final int offset = mSweepPadding.bottom * 2;
            mContentOffset.bottom -= offset;
            mMargins.bottom += offset;
        } else {
            final int heightAfter = heightBefore * 2;
            setMeasuredDimension(widthBefore, heightAfter);
            mContentOffset.offset(0, (heightAfter - heightBefore) / 2);

            final int offset = mSweepPadding.right * 2;
            mContentOffset.right -= offset;
            mMargins.right += offset;
        }

        mSweepOffset.offset(mContentOffset.left, mContentOffset.top);
        mMargins.offset(-mSweepOffset.x, -mSweepOffset.y);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        invalidateLabelOffset();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        final int width = getWidth();
        final int height = getHeight();

        final int labelSize;
        if (isEnabled() && mLabelLayout != null) {
            final int count = canvas.save();
            {
                final float alignOffset = mLabelSize - LARGE_WIDTH;
                canvas.translate(
                        mContentOffset.left + alignOffset, mContentOffset.top + mLabelOffset);
                mLabelLayout.draw(canvas);
            }
            canvas.restoreToCount(count);
            labelSize = (int) mLabelSize + mSafeRegion;
        } else {
            labelSize = 0;
        }

        if (mFollowAxis == VERTICAL) {
            mSweep.setBounds(labelSize, mSweepOffset.y, width + mContentOffset.right,
                    mSweepOffset.y + mSweep.getIntrinsicHeight());
        } else {
            mSweep.setBounds(mSweepOffset.x, labelSize, mSweepOffset.x + mSweep.getIntrinsicWidth(),
                    height + mContentOffset.bottom);
        }

        mSweep.draw(canvas);

        if (DRAW_OUTLINE) {
            mOutlinePaint.setColor(Color.RED);
            canvas.drawRect(0, 0, width, height, mOutlinePaint);
        }
    }

    public static float getLabelTop(ChartSweepView view) {
        return view.getY() + view.mContentOffset.top;
    }

    public static float getLabelBottom(ChartSweepView view) {
        return getLabelTop(view) + view.mLabelLayout.getHeight();
    }

    public static float getLabelWidth(ChartSweepView view) {
        return Layout.getDesiredWidth(view.mLabelLayout.getText(), view.mLabelLayout.getPaint());
    }
}
