/*
 * 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);

        final int color = a.getColor(R.styleable.ChartSweepView_labelColor, Color.BLUE);
        setSweepDrawable(a.getDrawable(R.styleable.ChartSweepView_sweepDrawable), color);
        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(color);

        // 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);
        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, int color) {
        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;
            // Match the text.
            mSweep.setTint(color);
            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 = DynamicLayout.Builder.obtain(mLabelTemplate, paint, LARGE_WIDTH)
                    .setAlignment(Alignment.ALIGN_RIGHT)
                    .setIncludePad(false)
                    .setUseLineSpacingFromFallbacks(true)
                    .build();
            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());
    }
}
