package cn.hzw.doodle;

import android.graphics.Canvas;
import android.graphics.PointF;

import java.util.ArrayList;
import java.util.List;

import cn.hzw.doodle.core.IDoodle;
import cn.hzw.doodle.core.IDoodleColor;
import cn.hzw.doodle.core.IDoodleItem;
import cn.hzw.doodle.core.IDoodleItemListener;
import cn.hzw.doodle.core.IDoodlePen;
import cn.hzw.doodle.core.IDoodleShape;

/**
 * Created on 29/06/2018.
 */

public abstract class DoodleItemBase implements IDoodleItem, IDoodleItemListener {

    public static final float MIN_SCALE = 0.01f;
    public static final float MAX_SCALE = 100f;

    private float mItemRotate; // item的旋转角度
    private IDoodle mDoodle;
    private PointF mLocation = new PointF();
    private IDoodlePen mPen; // 画笔类型
    private IDoodleShape mShape; // 画笔形状
    private float mSize; // 大小
    private IDoodleColor mColor; // 颜色
    private boolean mIsDrawOptimize = false; //优化绘制
    private boolean mIsNeedClipOutside = true; // 是否需要裁剪图片区域外的部分
    private float mPivotX, mPivotY;
    private float mMinScale = MIN_SCALE;
    private float mMaxScale = MAX_SCALE;
    private float mScale = 1;

    private boolean mHasAdded = false;

    private List<IDoodleItemListener> mItemListeners = new ArrayList<>();

    public DoodleItemBase(IDoodle doodle) {
        this(doodle, null);
    }

    public DoodleItemBase(IDoodle doodle, DoodlePaintAttrs attrs) {
        setDoodle(doodle);
        if (attrs != null) {
            mPen = attrs.pen();
            mShape = attrs.shape();
            mSize = attrs.size();
            mColor = attrs.color();
        }
    }

    @Override
    public void setDoodle(IDoodle doodle) {
        if (doodle != null && mDoodle != null) { // 不能重复赋予非空值
            throw new RuntimeException("item's doodle object is not null");
        }
        mDoodle = doodle;
        if (doodle == null) {
        }
    }

    @Override
    public IDoodle getDoodle() {
        return mDoodle;
    }

    @Override
    public void setPivotX(float pivotX) {
        mPivotX = pivotX;
        onPropertyChanged(PROPERTY_PIVOT_X);
    }

    @Override
    public float getPivotX() {
        return mPivotX;
    }

    @Override
    public void setPivotY(float pivotY) {
        mPivotY = pivotY;
        onPropertyChanged(PROPERTY_PIVOT_Y);
    }

    @Override
    public float getPivotY() {
        return mPivotY;
    }

    @Override
    public void setItemRotate(float textRotate) {
        mItemRotate = textRotate;
        onPropertyChanged(PROPERTY_ROTATE);
        refresh();
    }

    @Override
    public float getItemRotate() {
        return mItemRotate;
    }

    /**
     * 默认改变相应的中心点位置
     *
     * @param x
     * @param y
     */
    @Override
    public void setLocation(float x, float y) {
        setLocation(x, y, true);
    }

    /**
     * @param x
     * @param y
     * @param changePivot 是否随着移动相应改变中心点的位置
     */
    public void setLocation(float x, float y, boolean changePivot) {
        float diffX = x - mLocation.x, diffY = y - mLocation.y;
        mLocation.x = x;
        mLocation.y = y;

        onPropertyChanged(PROPERTY_LOCATION);

        if (changePivot) {
            mPivotX = mPivotX + diffX;
            mPivotY = mPivotY + diffY;
            onPropertyChanged(PROPERTY_PIVOT_X);
            onPropertyChanged(PROPERTY_PIVOT_Y);
        }

        refresh();
    }

    @Override
    public PointF getLocation() {
        return mLocation;
    }

    @Override
    public IDoodlePen getPen() {
        return mPen;
    }

    @Override
    public void setPen(IDoodlePen pen) {
        mPen = pen;
        refresh();
    }

    @Override
    public IDoodleShape getShape() {
        return mShape;
    }

    @Override
    public void setShape(IDoodleShape shape) {
        mShape = shape;
        refresh();
    }

    @Override
    public float getSize() {
        return mSize;
    }

    @Override
    public void setSize(float size) {
        mSize = size;
        onPropertyChanged(PROPERTY_SIZE);
        refresh();
    }

    @Override
    public IDoodleColor getColor() {
        return mColor;
    }

    @Override
    public void setColor(IDoodleColor color) {
        mColor = color;
        onPropertyChanged(PROPERTY_COLOR);
        refresh();
    }

    @Override
    public void draw(Canvas canvas) {
        drawBefore(canvas);

        int count = canvas.save();
        mLocation = getLocation(); // 获取旋转后的起始坐标
        canvas.translate(mLocation.x, mLocation.y); // 偏移，把坐标系平移到item矩形范围
        float px = mPivotX - mLocation.x, py = mPivotY - mLocation.y; // 需要减去偏移
        canvas.rotate(mItemRotate, px, py); // 旋转坐标系
        canvas.scale(mScale, mScale, px, py); // 缩放
        doDraw(canvas);
        canvas.restoreToCount(count);

        drawAfter(canvas);
    }

    /**
     * 是否优化绘制，若是则在添加item时提前会绘制到图片上，若否则在每次view绘制时绘制在View中，直到保存时才绘制到图片上
     *
     * @param drawOptimize
     */
    public void setDrawOptimize(boolean drawOptimize) {
        if (drawOptimize == mIsDrawOptimize) {
            return;
        }
        mIsDrawOptimize = drawOptimize;
    }

    @Override
    public boolean isNeedClipOutside() {
        return mIsNeedClipOutside;
    }

    @Override
    public void setNeedClipOutside(boolean clip) {
        mIsNeedClipOutside = clip;
    }

    @Override
    public void onAdd() {
        mHasAdded = true;
    }

    @Override
    public void onRemove() {
        mHasAdded = false;
    }

    @Override
    public void refresh() {
        if (mHasAdded && mDoodle != null) {
            mDoodle.refresh();
        }
    }

    @Override
    public boolean isDoodleEditable() {
        return false;
    }

    @Override
    public void setScale(float scale) {
        if (scale <= mMinScale) {
            scale = mMinScale;
        } else if (scale > mMaxScale) {
            scale = mMaxScale;
        }
        mScale = scale;
        onPropertyChanged(PROPERTY_SCALE);
        refresh();
    }

    @Override
    public float getScale() {
        return mScale;
    }

    public void setMinScale(float minScale) {
        if (mMinScale <= 0) {
            minScale = MIN_SCALE;
        } else if (minScale > mMaxScale) {
            minScale = mMaxScale;
        }
        mMinScale = minScale;
        setScale(getScale());
    }

    public float getMinScale() {
        return mMinScale;
    }

    public void setMaxScale(float maxScale) {
        if (maxScale <= 0) {
            maxScale = MIN_SCALE;
        } else if (maxScale < mMinScale) {
            maxScale = mMinScale;
        }
        mMaxScale = maxScale;
        setScale(getScale());
    }

    public float getMaxScale() {
        return mMaxScale;
    }

    @Override
    public void addItemListener(IDoodleItemListener listener) {
        if (listener == null || mItemListeners.contains(listener)) {
            return;
        }
        mItemListeners.add(listener);
    }

    @Override
    public void removeItemListener(IDoodleItemListener listener) {
        mItemListeners.remove(listener);
    }

    @Override
    public void onPropertyChanged(int property) {
        for (int i = 0; i < mItemListeners.size(); i++) {
            mItemListeners.get(i).onPropertyChanged(property);
        }
    }

    /**
     * 仅画在View上，在绘制涂鸦之前调用(相当于背景图，但是保存图片时不包含该部分)
     *
     * @param canvas 为View的Canvas
     */
    protected void drawBefore(Canvas canvas) {

    }

    /**
     * 绘制item，不限制Canvas
     *
     * @param canvas
     */
    protected abstract void doDraw(Canvas canvas);

    /**
     * 仅画在View上，在绘制涂鸦之后调用(相当于前景图，但是保存图片时不包含该部分)
     *
     * @param canvas 为View的Canvas
     */
    protected void drawAfter(Canvas canvas) {

    }

    /**
     * 画在所有item的上面
     *
     * @param canvas
     */
    @Override
    public void drawAtTheTop(Canvas canvas) {

    }

}
