/**
 * 视频相关接口、类
 */
import { callNativeSync } from './util';
import {is, checkParam, compareVersion} from "./util/commonFn";
import shortId from 'shortid';
/**
 * Video类
 * 唯一标识 __videoId 标记初始化的video唯一标识
 *
 * @class Video
 */

/**
 * 判断当前字符串是否在数组里
 *  不存在则设值，存在就不管
 * */
function judgeExist (source = '', target = []) {
    if (target.indexOf(source) < 0) {
        target.push(source)
    }
}

class Animation {
    constructor(obj) {
        // 全局变量，存在则设置。
        if(obj.duration) this.duration = obj.duration
        if(obj.timingFunction) this.timingFunction = obj.timingFunction
        if(obj.delay) this.delay = obj.delay
        if(obj.transformOrigin) this.transformOrigin = obj.transformOrigin
        this._temp = {
            transformOrder: []
        }
        this._stepArr = []
    }

    opacity(opacity) {
        // api 参数类型校验
        const isOk = checkParam([opacity], [
            {
                key: 'opacity',
                type: 'Number'
            }
        ], {name: 'opacity'});

        if (isOk) {
            this._temp.opacity = opacity.toString();
        }

        return this;
    }

    backgroundColor(color) {
        const isOk = checkParam([color], [
            {
                key: 'color',
                type: 'String'
            }
        ], {name: 'backgroundColor'});

        if (isOk) {
            this._temp.backgroundColor = color;
        }

        return this;
    }

    width(width) {
        const isOk = checkParam([width], [
            {
                key: 'width',
                type: ['String', 'Number']
            }
        ], {name: 'width'});

        if (isOk) {
            this._temp.width = width.toString();
        }

        return this;
    }

    height(height) {
        const isOk = checkParam([height], [
            {
                key: 'height',
                type: ['String', 'Number']
            }
        ], {name: 'height'});

        if (isOk) {
            this._temp.height = height.toString();
        }

        return this;
    }

    matrix(sx, ay, ax, sy, tx, ty) {
        const isOk = checkParam([sx, ay, ax, sy, tx, ty], [
            {
                key: 'sx',
                type: 'Number'
            },
            {
                key: 'ay',
                type: 'Number'
            },
            {
                key: 'ax',
                type: 'Number'
            },
            {
                key: 'sy',
                type: 'Number'
            },
            {
                key: 'tx',
                type: 'Number'
            },
            {
                key: 'ty',
                type: 'Number'
            },
        ], {name: 'matrix'});

        if (isOk) {
            this._temp.matrix = {sx,ay,ax,sy,tx,ty};
            judgeExist('matrix', this._temp.transformOrder);
        }

        return this;
    }

    matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4) {
        const isOk = checkParam([a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4], [
            {
                key: 'a1',
                type: 'Number'
            },
            {
                key: 'b1',
                type: 'Number'
            },
            {
                key: 'c1',
                type: 'Number'
            },
            {
                key: 'd1',
                type: 'Number'
            },
            {
                key: 'a2',
                type: 'Number'
            },
            {
                key: 'b2',
                type: 'Number'
            },
            {
                key: 'c2',
                type: 'Number'
            },
            {
                key: 'd2',
                type: 'Number'
            },
            {
                key: 'c1',
                type: 'Number'
            },
            {
                key: 'c2',
                type: 'Number'
            },
            {
                key: 'c3',
                type: 'Number'
            },
            {
                key: 'c4',
                type: 'Number'
            },
            {
                key: 'd1',
                type: 'Number'
            },
            {
                key: 'd2',
                type: 'Number'
            },
            {
                key: 'd3',
                type: 'Number'
            },
            {
                key: 'd4',
                type: 'Number'
            },
        ], {name: 'matrix3d'});

        if (isOk) {
            this._temp.matrix3d = {a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4};
            judgeExist('matrix3d', this._temp.transformOrder);
        }

        return this;
    }

    rotate(deg) {
        const isOk = checkParam([deg], [
            {
                key: 'deg',
                type: 'Number'
            }
        ], {name: 'rotate'});

        if (isOk) {
            this._temp.rotate = deg;
            judgeExist('rotate', this._temp.transformOrder);
        }

        return this;
    }

    rotate3d(x, y, z, deg) {
        const isOk = checkParam([x, y, z, deg], [
            {
                key: 'x',
                type: 'Number'
            },
            {
                key: 'y',
                type: 'Number'
            },
            {
                key: 'z',
                type: 'Number'
            },
            {
                key: 'deg',
                type: 'Number'
            }
        ], {name: 'rotate3d'});

        if (isOk) {
            this._temp.rotate3d = {x, y, z, deg};
            judgeExist('rotate3d', this._temp.transformOrder);
        }

        return this;
    }

    rotateX(deg) {
        const isOk = checkParam([deg], [
            {
                key: 'deg',
                type: 'Number'
            }
        ], {name: 'rotateX'});

        if (isOk) {
            this._temp.rotateX = deg;
            judgeExist('rotateX', this._temp.transformOrder);
        }

        return this;
    }

    rotateY(deg) {
        const isOk = checkParam([deg], [
            {
                key: 'deg',
                type: 'Number'
            }
        ], {name: 'rotateY'});

        if (isOk) {
            this._temp.rotateY = deg;
            judgeExist('rotateY', this._temp.transformOrder);
        }

        return this;
    }

    rotateZ(deg) {
        const isOk = checkParam([deg], [
            {
                key: 'deg',
                type: 'Number'
            }
        ], {name: 'rotateZ'});

        if (isOk) {
            this._temp.rotateZ = deg;
            judgeExist('rotateZ', this._temp.transformOrder);
        }

        return this;
    }

    scale(sx, sy = sx) {
        const isOk = checkParam([sx, sy], [
            {
                key: 'sx',
                type: 'Number'
            },
            {
                key: 'sy',
                type: 'Number'
            }
        ], {name: 'scale'});

        if (isOk) {
            this._temp.scale = {sx, sy};
            judgeExist('scale', this._temp.transformOrder);
        }

        return this;
    }

    scale3d(sx, sy, sz) {
        const isOk = checkParam([sx, sy, sz], [
            {
                key: 'sx',
                type: 'Number'
            },
            {
                key: 'sy',
                type: 'Number'
            },
            {
                key: 'sz',
                type: 'Number'
            }
        ], {name: 'scale3d'});

        if (isOk) {
            this._temp.scale3d = {sx, sy, sz};
            judgeExist('scale3d', this._temp.transformOrder);
        }

        return this;
    }

    scaleX(sx) {
        const isOk = checkParam([sx], [
            {
                key: 'sx',
                type: 'Number'
            }
        ], {name: 'scaleX'});

        if (isOk) {
            this._temp.scaleX = sx;
            judgeExist('scaleX', this._temp.transformOrder);
        }

        return this;
    }

    scaleY(sy) {
        const isOk = checkParam([sy], [
            {
                key: 'sy',
                type: 'Number'
            }
        ], {name: 'scaleY'});

        if (isOk) {
            this._temp.scaleY = sy;
            judgeExist('scaleY', this._temp.transformOrder);
        }

        return this;
    }

    scaleZ(sz) {
        const isOk = checkParam([sz], [
            {
                key: 'sz',
                type: 'Number'
            }
        ], {name: 'scaleZ'});

        if (isOk) {
            this._temp.scaleZ = sz;
            judgeExist('scaleZ', this._temp.transformOrder);
        }

        return this;
    }

    skew(ax, ay = 0) {
        const isOk = checkParam([ax, ay], [
            {
                key: 'ax',
                type: 'Number'
            },
            {
                key: 'ay',
                type: 'Number'
            }
        ], {name: 'skew'});

        if (isOk) {
            this._temp.skew = {ax, ay};
            judgeExist('skew', this._temp.transformOrder);
        }

        return this;
    }

    skewX(ax) {
        const isOk = checkParam([ax], [
            {
                key: 'ax',
                type: 'Number'
            }
        ], {name: 'skewX'});

        if (isOk) {
            this._temp.skewX = ax;
            judgeExist('skewX', this._temp.transformOrder);
        }

        return this;
    }

    skewY(ay) {
        const isOk = checkParam([ay], [
            {
                key: 'ay',
                type: 'Number'
            }
        ], {name: 'skewY'});

        if (isOk) {
            this._temp.skewY = ay;
            judgeExist('skewY', this._temp.transformOrder);
        }

        return this;
    }

    translate(tx, ty = 0) {
        const isOk = checkParam([tx, ty], [
            {
                key: 'tx',
                type: 'Number'
            },
            {
                key: 'ty',
                type: 'Number'
            }
        ], {name: 'translate'});

        if (isOk) {
            this._temp.translate = {tx, ty};
            judgeExist('translate', this._temp.transformOrder);
        }

        return this;
    }

    translate3d(tx, ty = 0, tz = 0) {
        const isOk = checkParam([tx, ty, tz], [
            {
                key: 'tx',
                type: 'Number'
            },
            {
                key: 'ty',
                type: 'Number'
            },
            {
                key: 'tz',
                type: 'Number'
            }
        ], {name: 'translate3d'});

        if (isOk) {
            this._temp.translate3d = {tx, ty, tz};
            judgeExist('translate3d', this._temp.transformOrder);
        }

        return this;
    }

    translateX(tx) {
        const isOk = checkParam([tx], [
            {
                key: 'tx',
                type: 'Number'
            }
        ], {name: 'translateX'});

        if (isOk) {
            this._temp.translateX = tx;
            judgeExist('translateX', this._temp.transformOrder);
        }

        return this;
    }

    translateY(ty) {
        const isOk = checkParam([ty], [
            {
                key: 'ty',
                type: 'Number'
            }
        ], {name: 'translateY'});

        if (isOk) {
            this._temp.translateY = ty;
            judgeExist('translateY', this._temp.transformOrder);
        }

        return this;
    }

    translateZ(tz) {
        const isOk = checkParam([tz], [
            {
                key: 'tz',
                type: 'Number'
            }
        ], {name: 'translateZ'});

        if (isOk) {
            this._temp.translateZ = tz;
            judgeExist('translateZ', this._temp.transformOrder);
        }

        return this;
    }

    step(obj = {}) {
        const isOk = checkParam([obj], [
            {
                key: 'obj',
                type: 'Object'
            }
        ], {name: 'step'});

        if (isOk) {
            this._stepArr.push(Object.assign({}, this._temp, {
                additionalConfiguration: obj
            }));
            this._temp = {
                transformOrder: []
            }
        }

        return this;
    }

    export() {
        let _shortId = shortId.generate();
        let _output = {
            // 全局动画属性
            configuration: {
                transformOrigin: this.transformOrigin,
                duration: this.duration,
                timingFunction: this.timingFunction,
                delay: this.delay
            },
            // 组件所在的 pageId
            pageId: global.__biliCacheData.getCurrentPageId(),
            // 动画 id
            animationId: _shortId,
            steps: this._stepArr
        }

        callNativeSync('animation.export', _output);

        this._stepArr = []
        this._temp = {
            transformOrder: []
        }

        return _shortId
    }

}

export default {
    /**
     * 创建内部 Video类 上下文 createVideoContext 对象。
     *
     * @returns {Video}
     */
    createAnimation(obj = {
        duration: 400,
        timingFunction: 'linear',
        delay: 0,
        transformOrigin: '50% 50% 0'
    }) {
        return new Animation(obj);
    },
};
