/**
 * 画笔板擦模块，提供全局的画笔、板擦功能
 * Author: luxing@iflytek.com
 * @version 1.0
 * @module toolbarmgr
 */

define(function (require, exports, module) {

    /**
     * 工具类别
     * @enum
     * @type {{Mouse: string, Pen: string, Eraser: string}}
     */
    var ToolType = {
        Mouse: 'mouse',
        Pen: 'pen',
        Eraser: 'eraser'
    }
    var EraserSize = {
        Big: 54
    }

    /**
     * @constructor
     */
    function PaintCanvas() {
        var _self = this;

        /** @type {jQuery} */
        var _canvasContainer = $('<div/>').attr('class', 'paint_container').css({'position':'absolute','left':'0px','top':'0px','width': '100%', 'height': '100%'});

        /** @type {jQuery} */
        var _strokeCanvas;
        /** @type {CanvasRenderingContext2D} */
        var _strokeContext;

        var _curPenSize = 4;
        var _curPenColor = "red";
        var _curEraserSize = EraserSize.Big;
        var _isPainting = false;
        var _curTool = ToolType.Mouse;
        var _curCursor = "auto";
        var _lastSelectedPenColor;
        var _isCurNewBlankPage = false;

        /**
         * 返回基础画布canvas对象
         * @returns {jQuery}
         */
        this.getStrokeCanvas = function () {
            return _strokeCanvas;
        }

        /**
         * 返回当前画布图像base64数据
         * @returns {base64}
         */
        this.getStrokeCanvasDataUrl = function () {
            return _strokeCanvas[0].toDataURL();
        }

        /**
         * 加载画布图像
         * @param {base64} dataUrl
         * @param needChangeToPenMode{boolean} 是否需要切换到画笔模式
         */
        this.loadStrokeCanvasFromDataUrl = function(dataUrl,needChangeToPenMode){
            var def = $.Deferred();
            _self.clearCanvas();
            _strokeContext.globalCompositeOperation = "source-over";
            if(dataUrl){
                var img = new Image();
                img.src = dataUrl;
                img.onload = function(){
                    _strokeContext.drawImage(img,0,0);
                    def.resolve();
                }
            }else{
                def.resolve();
            }
            if(needChangeToPenMode){
                _self.changeToPenMode();
                _isCurNewBlankPage = true;
            }else{
                _isCurNewBlankPage = false;
            }
            return def.promise();
        }

        /**
         * 切换到鼠标模式，留给翻页时调用
         */
        this.changeToMouseMode = function(){
            _changeToMode(ToolType.Mouse);
        }

        /**
         * 切换到画笔模式，留给新建页时调用
         */
        this.changeToPenMode = function(){
            _changeToMode(ToolType.Pen);
            $("#penSelectorDiv").hide();
        }

        /**
         * 返回画布父容器Div
         * @returns {jQuery}
         */
        this.getCanvasContainer = function () {
            return _canvasContainer;
        }

        /**
         * 初始化画布
         */
        this.init = function () {
            _bindClickEventsToMainUI();
            _changeToMode(ToolType.Mouse);
        }

        /**
         * 卸载画布
         */
        this.disposePaintCanvas = function () {
            _canvasContainer.find(".pen_canvas").remove();
            _strokeCanvas=null;
        }

        /**
         * 清空canvas
         */
        this.clearCanvas = function () {
            if(_strokeContext){
                //console.log(_strokeCanvas.width(),_strokeCanvas.height());
                _strokeContext.clearRect(0, 0, _strokeCanvas.width(), _strokeCanvas.height());
            }
        }

        /**
         * 设置画笔颜色
         * @param {String} color 颜色值
         * @private
         */
        function _setColor(color) {
            if (_strokeContext != null) {
                _strokeContext.strokeStyle = color;
                _strokeContext.fillStyle = color;
                _curPenColor = color;
            }
        }

        /**
         * 设置画笔、板擦粗细
         * @param {String} tool 给哪个工具设置大小,pen,eraser
         * @param {Number} size 笔迹大小
         */
        function _setSize(tool, size) {
            if (_strokeContext) {
                _strokeContext.lineWidth = size;
                _strokeContext.lineJoin = 'round';
                _strokeContext.lineCap = 'round';
                if (tool === ToolType.Pen) {
                    _curPenSize = size;
                } else if (tool === ToolType.Eraser) {
                    _curEraserSize = size;
                }
            }
        }

        /**
         * 设置鼠标样式
         * @param {String} cursor
         */
        function _setCursor(cursor) {
            if (_strokeCanvas) {
                _strokeCanvas.css("cursor", cursor);
                _curCursor = cursor;
            }
        }

        /**
         * 设置工具类型
         * @param {String} toolType 设置成哪个工具
         */
        function _changeToMode(toolType) {
            $("#penSelectorDiv").hide();
            $("#eraserSelectorDiv").hide();

            if (toolType === ToolType.Mouse) {
                _curTool = ToolType.Mouse;
                _createCanvas();
                $("#cursorHackDiv").hide();
                _strokeCanvas.unbind();
                _strokeCanvas.css("pointer-events","none");
                _canvasContainer.css("pointer-events","none");
            }
            if (toolType === ToolType.Pen) {
                //这里要先设置curtool，后面的bindCommands会用到
                _curTool = ToolType.Pen;
                _createCanvas();
                _bindCommands();
                _strokeContext.globalCompositeOperation = "source-over";
                _setSize(ToolType.Pen, _curPenSize);
                _setColor(_curPenColor);
                _strokeCanvas.css("cursor", "url(player/assert/images/penCursor.cur),auto");
                $("#cursorHackDiv").hide();
                $("#penSelectorDiv").show();
                _strokeCanvas.css("pointer-events","auto");
                _canvasContainer.css("pointer-events","auto");
            }
            if (toolType === ToolType.Eraser) {
                _curTool = ToolType.Eraser;
                _createCanvas();
                _bindCommands();
                _strokeContext.globalCompositeOperation = "destination-out";
                _setSize("eraser", _curEraserSize);
                _strokeCanvas.css("cursor", "url(player/assert/images/bc_54f.cur),auto");
                $("#cursorHackDiv").show();
                $("#eraserSelectorDiv").show();
                _strokeCanvas.css("pointer-events","auto");
                _canvasContainer.css("pointer-events","auto");
            }
        }

        /**
         * @description 创建绘图的canvas
         */
        function _createCanvas() {
            if (!_strokeCanvas) {
                _strokeCanvas = $("<canvas>").attr("class", 'pen_canvas')
                    .css({
                        "position": "absolute",
                        "left": "0px",
                        "top": "0px",
                        "zIndex":3
                    });
                _canvasContainer.append(_strokeCanvas);
                $("#mainContainer").append(_canvasContainer);
                _strokeCanvas.attr("width", _canvasContainer.width());
                _strokeCanvas.attr("height", _canvasContainer.height());
                _strokeContext = _strokeCanvas[0].getContext("2d");
            } else {
                _canvasContainer.show();
                _canvasContainer.append(_strokeCanvas);
                $("#mainContainer").append(_canvasContainer);
                _strokeCanvas.show();
            }
        };

        /**
         * 绑定绘制笔迹的事件
         */
        function _bindCommands() {
            _strokeCanvas.unbind();
            var startPoint = {x:0,y:0};
            var endPoint = {x:0,y:0};
            _isPainting=false;
            _strokeCanvas.mousedown(function (evt) {
                $("#penSelectorDiv").hide();
                $("#eraserSelectorDiv").hide();

                var startX = evt.offsetX;
                var startY = evt.offsetY;
                _strokeContext.beginPath();
                if (_curTool === ToolType.Pen) {
                    //在仅仅点击鼠标时，需要画出一个点，如果不加上这0.01个像素，则画不出来
                    startPoint.x = startX + 4.5;
                    startPoint.y = startY + 4.5;
                    endPoint.x = startX + 4.5 + 0.01;
                    endPoint.y = startY + 4.5 + 0.01;
                    _setSize("pen", _curPenSize);
                    _setColor(_curPenColor);
                    _strokeContext.moveTo(startPoint.x, startPoint.y);
                    _strokeContext.lineTo(endPoint.x, endPoint.y);
                    _strokeContext.stroke();
                } else if (_curTool === ToolType.Eraser) {
                    startPoint.x = startX;
                    startPoint.y = startY;
                    _strokeContext.clearRect(startPoint.x, startPoint.y, _curEraserSize, _curEraserSize);
                    //解决bug：翻页时为了将笔迹恢复而改成了source-over，但是板擦状态下需要改回来
                    _strokeContext.globalCompositeOperation = "destination-out";
                    //解决bug:单双页切换时板擦大小问题
                    _setSize(ToolType.Eraser, _curEraserSize);
                }
                _isPainting = true;
                GlobalStage.slidesArray[GlobalStage._curSlidePageIndex].penData = true;
            })
            _strokeCanvas.mousemove(function (evt) {
                if (_isPainting) {
                    if (_curTool === ToolType.Pen) {
                        endPoint.x = evt.offsetX + 4.5;
                        endPoint.y = evt.offsetY + 4.5;
                        _strokeContext.lineTo(endPoint.x, endPoint.y);
                        _strokeContext.stroke();
                    } else if (_curTool === ToolType.Eraser) {
                        endPoint.x = evt.offsetX;
                        endPoint.y = evt.offsetY;
                        _strokeContext.clearRect(endPoint.x, endPoint.y, _curEraserSize, _curEraserSize);
                    }
                }
            })
            _strokeCanvas.mouseup(function () {
                _isPainting = false;
            });
            _strokeCanvas.mouseout(function () {
                _curTool===ToolType.Pen&&(_isPainting = false);
            });
        }

        /**
         * 给页面元素绑定点击事件
         */
        function _bindClickEventsToMainUI() {
            //全局鼠标
            $('#btnMouse').click(function () {
                _changeToMode(ToolType.Mouse);
            });

            //全局画笔
            $('#btnPen').click(function () {
                if(_curPenColor === "red"){
                    $("#btnRedPen").find("span").css({"border":"2px solid #ffe294","marginLeft":"-1px","marginTop":"-1px"});
                }
                if(_curPenColor === " white"){
                    $("#btnBluePen").find("span").css({"border":"2px solid #ffe294","marginLeft":"-1px","marginTop":"-1px"});
                }
                if(_curPenColor === "black"){
                    $("#btnBlackPen").find("span").css({"border":"2px solid #ffe294","marginLeft":"-1px","marginTop":"-1px"});
                }
                _changeToMode(ToolType.Pen);
            });

            //画笔颜色选择
            $("#penSelector").children().click(function(){
                _changeToMode(ToolType.Pen);
                _setColor($(this).attr("pcolor"));
                $("#penSelector").children().find("span").css({"border":"1px solid #eae8e8"});
                $(this).find("span").css({"border":"2px solid #ffe294","marginLeft":"-1px","marginTop":"-1px"});
            });

            //全局板擦
            $('#btnEraser').click(function () {
                _changeToMode(ToolType.Eraser);
            });

            //板擦选择
            $("#eraserSelector").find("img").click(function(event){
                if($(this).attr("etype") === "point"){
                    _changeToMode(ToolType.Eraser);
                };
                if($(this).attr("etype") === "clear"){
                    _self.clearCanvas();
                    if(_isCurNewBlankPage){
                        _changeToMode(ToolType.Pen);
                        $("#penSelectorDiv").hide();
                    }else{
                        _changeToMode(ToolType.Mouse);
                    }
                };
                event.preventDefault();
            });
        }
    }

    exports.PaintCanvas = new PaintCanvas();
});