/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .F88X
 *        X8888Y
 *      .}888888N;
 *        i888888N;        .:!              .I$WI:
 *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
 *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
 *            +888888N;  .8888888Y                                  "&&8Y.}8,
 *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
 *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
 *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
 *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
 *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
 *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
 *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
 *      .:R888888I
 *      .&888888I                                          Copyright (c) 2016-2020.  博锐尚格科技股份有限公司
 *        ~8888'
 *        .!88~                                                                     All rights reserved.
 *
 * *********************************************************************************************************************
 */

import { SPainter, SRect, SSize, SColor, SPoint } from "@persagy-web/draw";
import { SImageShowType, STextOrigin } from "@persagy-web/graph";
import { SGraphItem, SAnchorItem,SLineStyle } from "@persagy-web/graph";
import { SItemStatus } from "@persagy-web/big";
import { SGraphEdit } from "./../"

/**
 * 图片编辑类
 *
 * @author  韩耀龙(han_yao_long@163.com)
 */
export class SImageEdit extends SGraphEdit {
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //属性
    /** 图片dom */
    img: CanvasImageSource | undefined;
    /** 展示模式 */
    private _showType: SImageShowType = SImageShowType.Full;
    get showType(): SImageShowType {
        return this._showType;
    }
    set showType(v: SImageShowType) {
        this._showType = v;
        this.computeImgSize();
        this.update();
    }
    /** 边框色 */
    private _strokeColor: SColor = SColor.Transparent;
    get strokeColor(): SColor {
        return this._strokeColor;
    }
    set strokeColor(v: SColor) {
        this._strokeColor = v;
        this.update();
    }

    /** 边框宽度 */
    private _lineWidth: number = 1;
    get lineWidth(): number {
        return this._lineWidth;
    }
    set lineWidth(v: number) {
        this._lineWidth = v;
        this.update();
    }
    /** 原点位置    */
    private _originPosition: STextOrigin = STextOrigin.LeftTop;
    get originPosition(): STextOrigin {
        return this._originPosition;
    }
    set originPosition(v: STextOrigin) {
        this._originPosition = v;
        this.update();
    }

    /** 线条样式    */
    private _lineStyle: SLineStyle = SLineStyle.Solid;
    get lineStyle(): SLineStyle {
        return this._lineStyle;
    }
    set lineStyle(v: SLineStyle) {
        this._lineStyle = v;
        this.update();
    }
    /** 图片加载是否完成 */
    isLoadOver: boolean = false;

    /** 图片的宽度 */
    private imgWidth: number = this.width;

    /** 图片的高度 */
    private imgHeight: number = this.height;

    /** 图片地址 */
    private _url: string = "";
    get url(): string {
        return this._url;
    }
    set url(v: string) {
        this._url = v;
        this.img = new Image();
        this.img.onload = (e): void => {
            // @ts-ignore
            const imgSrc = e.path[0].src;
            if (this.isUrlIdentical(imgSrc)) {
                this.isLoadOver = true;
                this.computeImgSize();
                this.$emit("imgLoadOver");
                this.update();
            }
        };
        this.img.onerror = (e): void => {
            // @ts-ignore
            const imgSrc = e.path[0].src;
            if (this.isUrlIdentical(imgSrc)) {
                this.isLoadOver = false;
                this.$emit("imgLoadOver");
                this.update();
                console.log("加载图片错误！", e);
            }
        };
        this.img.src = v;
    }
    /** 锚点list  */
    anchorList: SAnchorItem[] = [];
    /** 宽度  */
    private _width: number = 64;
    /** 原点  */
    origin = new SPoint();
    get width(): number {
        return this._width;
    }
    set width(v: number) {
        if (v > 0) {
            if (v != this._width) {
                let w = this._width;
                this._width = v;
                this.onResize(
                    new SSize(w, this._height),
                    new SSize(this._width, this._height)
                );
            }
        }
    }

    /** 高度  */
    private _height: number = 64;
    get height(): number {
        return this._height;
    }
    set height(v: number) {
        if (v > 0) {
            if (v != this._height) {
                let h = this._height;
                this._height = v;
                this.onResize(
                    new SSize(this._width, h),
                    new SSize(this._width, this._height)
                );
            }
        }
    }
    /**编辑状态 */
    protected _status: SItemStatus = SItemStatus.Normal;
    get status(): SItemStatus {
        return this._status;
    }
    set status(value: SItemStatus) {
        const oldStatus = this._status;
        const newStatus = value;
        this._status = value;
        //状态变更触发事件
        this.$emit('StatusChange', oldStatus, newStatus)
        this.update();
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //函数
    /**
     * 构造函数
     *
     * @param   parent      指向父对象
     */
    constructor(parent: SGraphItem | null, url?: string) {
        super(parent);
        if (url) this.url = url;
        // this.initItem();
        this.origin = new SPoint(this.width / 2, this.height / 2);
    }

    /**
     * 将类中得数据转换为方便存储格式的方法
     *
     * return   any         针对item类型保持相应的格式
     */
    toData(): any {

    }

    /**
     * 根据显示模式计算图片的宽高
     */
    computeImgSize(): void {
        if (this.isLoadOver) {
            // 要绘制图片的宽度
            let width = 0;
            // 要绘制图片的宽度
            let height = 0;
            // 图片item的宽高比
            let itemAspectRatio: number = this.width / this.height;
            // 原始图片的宽高比
            let imgAspectRatio: number =
                // @ts-ignore
                (this.img.width as number) / (this.img.height as number);
            // 原始图片的高宽比
            let imgHwRatio: number =
                // @ts-ignore
                (this.img.height as number) / (this.img.width as number);
            if (this.showType == SImageShowType.Full) {
                width = this.width;
                height = this.height;
            } else if (this.showType == SImageShowType.Equivalency) {
                if (itemAspectRatio > imgAspectRatio) {
                    height = this.height;
                    width = imgAspectRatio * height;
                } else if (itemAspectRatio < imgAspectRatio) {
                    width = this.width;
                    height = width * imgHwRatio;
                } else {
                    width = this.width;
                    height = this.height;
                }
            } else if (this.showType == SImageShowType.AutoFit) {
                // @ts-ignore
                this.width = this.img.width as number;
                // @ts-ignore
                this.height = this.img.height as number;
                width = this.width;
                height = this.height;
            }
            this.imgWidth = width;
            this.imgHeight = height;
            // 设置原点位置(默认左上角)
            if (this.originPosition == STextOrigin.Centrum) {
                this.origin = new SPoint(this.width / 2, this.height / 2);
            }
        }
        this.origin = new SPoint(this.width / 2, this.height / 2);
        this.update();
    } // Function computeImgSize()

    /**
     * 判断当前地址和回调地址是否相同
     *
     * @param   imgUrl      图片回调地址
     * @return  当前地址和回调地址是否相同
     */
    private isUrlIdentical(imgUrl: string): boolean {
        if (this.url.indexOf("://") == -1) {
            // eslint-disable-next-line max-len
            const reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
            if (reg.test(this.url)) {
                return this.url == imgUrl;
            } else {
                return this.url == this.GetUrlRelativePath(imgUrl);
            }
        } else {
            return this.url == imgUrl;
        }
    } // Function isUrlIdentical()

    /**
     * 截取绝对路径中的相对路径
     * @param   url      绝对路径
     *
     */
    private GetUrlRelativePath(url: string): string {
        const arrUrl = url.split("//");
        const start = arrUrl[1].indexOf("/");
        const relUrl = arrUrl[1].substring(start);
        return relUrl;
    } // Function GetUrlRelativePath()

    /**
     * 大小改变
     */
    resize(oldSize: SRect, newSize: SRect): void {
        this.width = newSize.width;
        this.height = newSize.height;
        this.update()
    }

    /**
     * Item对象边界区域
     *
     * @return	SRect
     */
    boundingRect(): SRect {
        return new SRect(
            -this.origin.x,
            -this.origin.y,
            this.width * 1,
            this.height * 1
        );
    } // Function boundingRect()

    /**
   * 宽高发发生变化
   *
   * @param   oldSize 改之前的大小
   * @param   newSize 改之后大小
   * */
    protected onResize(oldSize: SSize, newSize: SSize): void {
        this.computeImgSize();
        this.update();
    } // Function onResize()

    /**
     * Item绘制操作
     *
     * @param   painter      绘画类
     */
    onDraw(painter: SPainter): void {
        painter.translate(-this.origin.x, -this.origin.y);
        if (this.isLoadOver) {
            // @ts-ignore
            painter.drawImage(this.img, 0, 0, this.imgWidth, this.imgHeight);
        }
        if (this.selected) {
            painter.shadow.shadowBlur = 10;
            painter.shadow.shadowColor = new SColor(`#00000033`);
            painter.shadow.shadowOffsetX = 5;
            painter.shadow.shadowOffsetY = 5;
        } else {
            painter.shadow.shadowColor = SColor.Transparent;
        }
        if (this.lineStyle == SLineStyle.Dashed) {
            painter.pen.lineDash = [
                painter.toPx(this.lineWidth * 3),
                painter.toPx(this.lineWidth * 7)
            ];
        } else if (this.lineStyle == SLineStyle.Dotted) {
            painter.pen.lineDash = [
                painter.toPx(2 * this.lineWidth),
                painter.toPx(2 * this.lineWidth)
            ];
        }
        painter.pen.lineWidth = this.lineWidth;
        painter.pen.color = this.strokeColor;
        painter.brush.color = SColor.Transparent;
        painter.drawRect(0, 0, this.width, this.height);
    } // Function onDraw()

} // Class SImageItem