﻿function getPosition(e) {
    var p = $(e).offset();

    return { x: p.left, y: p.top };
}

function mouseCoords(ev) {
    if (ev.pageX || ev.pageY) {
        return { x: ev.pageX, y: ev.pageY };
    }
    var body = document.body;
    return {
        x: ev.clientX + body.scrollLeft - body.clientLeft,
        y: ev.clientY + body.scrollTop - body.clientTop
    };
}

function getMouseOffset(size) {
    return { x: Math.floor(size / 2), y: Math.floor(size / 2) };
}

function MouseHandler(brdWrapper) {
    this.dragObject = null;
    this.mouseOffset = null;
    var conSq = [];
    this.dropTargets = [];
    var promData;
    var promoting = false;
    var board = brdWrapper.board;
    var gui = brdWrapper.gui;
    var boardPosition = null;

	this.controlledSquares =
	function (fromX, fromY) {
	    var result = [];
	    piece = brdWrapper.board.squares[fromX][fromY].piece;
	    if (piece != undefined && piece.color == board.currentMove) {
	        result = eval("brdWrapper.rules." + piece.name + "(\"" + fromX + "\", " + fromY + ", \"" + piece.color + "\")");
	    }	    
	    return result;
	}

	this.makeMoveable =
	function (item) {
	    $(item).mousemove(brdWrapper, function (ev) {
	        if (!brdWrapper.mouseHandler.dragObject)
	            return true;
	        var handler = brdWrapper.mouseHandler,
	            mousePos = mouseCoords(ev),
	            st = handler.dragObject.style,
                moOf = handler.mouseOffset;

	        st.top = (mousePos.y - boardPosition.top - moOf.y) + "px";
	        st.left = (mousePos.x - boardPosition.left - moOf.x) + "px";
	        return true;
	    });
	}

    this.addDropTarget =
	function (dropTarget) {
	    this.dropTargets.push(dropTarget);
	}

	var letters = ["a", "b", "c", "d", "e", "f", "g", "h"];
	var letter = [];
	letter["a"] = 1;
	letter["b"] = 2;
	letter["c"] = 3;
	letter["d"] = 4;
	letter["e"] = 5;
	letter["f"] = 6;
	letter["g"] = 7;
	letter["h"] = 8;

	function truncate(n) {
	    return Math.round(n - 0.5);
	}

	this.mouseDown =
    function (ev) {
        var gui = brdWrapper.gui;
        if (gui.BoardDisabled)
            return false;
        if (brdWrapper.visibleCols != 8 || brdWrapper.visibleRows != 8) {
            return false;
        }

        var handler = brdWrapper.mouseHandler;
        var mousePos = mouseCoords(ev);
        var brd = brdWrapper.boardTable;

        boardPosition = $(brd.rows[0].cells[0]).offset();

        var sq = brd.rows[1].cells[1];
        var pos = $(sq).offset();
        var xpos = Math.abs(truncate((mousePos.x - pos.left) / brdWrapper.squareSize)) + 1;
        var ypos = truncate((mousePos.y - pos.top) / brdWrapper.squareSize) + 1;

        if (xpos < 1 || xpos > 8 || ypos < 1 || ypos > 8) {
            return false;
        }

        var obj = brd.rows[ypos].cells[xpos].children[0];
        if (obj) {
            var tempSq;
            var boardPos = gui.getSquare('square' + xpos + ypos);
            conSq = handler.controlledSquares(boardPos.x, boardPos.y);
            if (conSq && conSq.length > 0) {
                for (var i = 0; i < conSq.length; i++) {
                    tempSq = gui.getGUISquare(conSq[i].charAt(0), conSq[i].charAt(1));
                    tempSq.className += " controlled";
                    handler.dropTargets.push(tempSq);
                }
            }
            else {
                return false;
            }

            handler.mouseOffset = getMouseOffset(
                    brdWrapper.squareSize);
            obj.style.position = 'absolute';
            obj.style.top = (mousePos.y - boardPosition.top - handler.mouseOffset.y) + "px";
            obj.style.left = (mousePos.x - boardPosition.left - handler.mouseOffset.x) + "px";
            handler.dragObject = obj;
            return false;
        }
    }

    this.mouseUp =
    function (item) {
        $(item).mouseup(brdWrapper, function (ev) {
            if (brdWrapper.mouseHandler.dragObject == null)
                return true;
            var handler = brdWrapper.mouseHandler;
            var gui = brdWrapper.gui;
            var board = brdWrapper.board;
            var PlayController = brdWrapper.playController;

            var mousePos = mouseCoords(ev);
            var promoting = false;

            for (var i = 0; i < handler.dropTargets.length; i++) {
                var curTarget = handler.dropTargets[i];
                var targPos = getPosition(curTarget);
                var targWidth = parseInt(curTarget.clientWidth);
                var targHeight = parseInt(curTarget.clientHeight);

                var Board = brdWrapper.boardTable;
                var boardPos = getPosition(Board);

                if ((mousePos.x > targPos.x) && (mousePos.x < (targPos.x + targWidth)) && (mousePos.y > targPos.y) &&
		(mousePos.y < (targPos.y + targHeight))) {
                    var coords = gui.getSquare(brdWrapper.mouseHandler.dragObject.className);
                    var piece = board.squares[coords.x][coords.y].piece;
                    var square = piece.square;
                    var oldSquare = gui.getGUISquare(square.x, square.y);
                    var curCoords = gui.getSquare(curTarget.className);
                    var currSquare = gui.getGUISquare(curCoords.x, curCoords.y);

                    if (piece.name == "pawn" && (curCoords.y == 1 || curCoords.y == 8)) {
                        var promBox = brdWrapper.promotionView; //                      
                        $(promBox).data('move', 'p' + square.x + square.y + curCoords.x + curCoords.y);
                        //выставляем нужный цвет
                        var pieceNames = ['queen', 'rook', 'bishop', 'knight']
                        for (var i in pieceNames) {
                            var name = pieceNames[i];
                            $(promBox).find('.' + name)[0].className = name + ' piece ' + brdWrapper.board.currentMove.charAt(0) + name;
                        }
                        brdWrapper.gui.BoardDisabled = true;
                        promBox.style.position = 'absolute';
                        $(promBox).css('left', $(Board).width() / 2 - $(promBox).width() / 2 + 'px');
                        $(promBox).css('top', $(Board).height() / 2 - $(promBox).height() / 2 + 'px');

                        $(promBox).fadeIn();

                        promoting = true;
                        $(oldSquare).children().remove();
                        $(currSquare).append(brdWrapper.mouseHandler.dragObject);
                        brdWrapper.mouseHandler.dragObject.style.position = 'static'
                    } else {
                        var c = piece.name.charAt(0).toLowerCase();
                        if (piece.name == "knight")
                            c = 'n';

                        var movingPiece = brdWrapper.mouseHandler.dragObject;
                        brdWrapper.mouseHandler.dragObject = null;

                        PlayController.MoveMade(c + square.x + square.y + curCoords.x + curCoords.y, function (result) {
                            movingPiece.style.position = 'static';
                            if (result) {
                                gui.makeMove(piece.name, square.x, square.y, curCoords.x, curCoords.y, null);
                            }
                        });

                        break;
                    }
                }

            }

            if (!promoting && brdWrapper.mouseHandler.dragObject)
                brdWrapper.mouseHandler.dragObject.style.position = 'static';
            brdWrapper.mouseHandler.dropTargets = [];
            for (var j = 0; j < conSq.length; j++) {
                var tempSq = gui.getGUISquare(conSq[j].charAt(0), conSq[j].charAt(1));
                $(tempSq).removeClass("controlled");
            }
            conSq = [];
            brdWrapper.mouseHandler.dragObject = null;
            return true;
        });
    }
}
