oglimmer/ggo

View on GitHub
web/src/main/webapp/js/app/Board.js

Summary

Maintainability
B
5 hrs
Test Coverage
define(['jquery', 'app/Constants', 'app/Communication', 'app/GlobalData', 'app/CursorUtil'], function($, Constants, communication, globalData, cursorUtil) {    
    
    function sortById(source) {
        var array = [];
        for(var att in source) {
            array.push(source[att]);
        }
        array.sort(function(a,b){
            return a.id < b.id ? -1 : a.id == b.id ? 0 : 1;
        });
        return array;
    }

    /*private class Board*/
    function Board(elementId) {
        this.elementId = elementId;
    }
    
    /*public*/ Board.prototype.init = function(evt) {
        console.log(this.elementId);
        this.canvasBoard = document.getElementById(this.elementId);
        this.ctxBoard = this.canvasBoard.getContext('2d');

        var thiz = this;
        $(document).ready(function() {
            $("#"+thiz.elementId).click(function(evt) {
                thiz.clickHandler(evt);
            });
        });
    }

    /*private*/ Board.prototype.clickHandler = function(evt) {
        
        var relMousePos = cursorUtil.getRelativeMousePos(evt, this.canvasBoard);
        
        if(this.clickHandlerModalDialog(relMousePos)) {
            return;
        }
        
        var selectedHex = this.getFieldByPos(relMousePos);
        if (selectedHex != null) {
            this.clickHandlerFieldUnit(selectedHex);
        } else {
            this.clickHandlerHandItemButtons(relMousePos);
        }
        
    }
    
    /*private*/ Board.prototype.clickHandlerModalDialog = function(relMousePos) {
        if(typeof globalData.model.modalDialogState !== 'undefined' 
            && globalData.model.modalDialogState != null
            && globalData.model.modalDialogState.show) {
            globalData.model.modalDialogState.onSelect(relMousePos);
            return true;
        }
        return false;
    }
    /*private*/ Board.prototype.clickHandlerFieldUnit = function(selectedHex) {
        if (typeof selectedHex.onSelect !== 'undefined') {
            selectedHex.onSelect();
        }                    

        var allUnits = globalData.model.boardState.idToUnits;
        for ( var unitProp in allUnits) {
            var unit = allUnits[unitProp];
            if (unit.x == selectedHex.x && unit.y == selectedHex.y) {
                if (typeof unit.onSelect !== 'undefined') {
                    unit.onSelect();
                }                    
            }
        }
    }
    /*private*/ Board.prototype.clickHandlerHandItemButtons = function(relMousePos) {
        function check(items) {
            $.each(items, function(index, item) {
                if(item.x <= relMousePos.x && item.y <= relMousePos.y 
                        && item.x+item.getWidth() >= relMousePos.x && item.y+item.getHeight() >= relMousePos.y) {
                    if (typeof item.onSelect !== 'undefined' ) {
                        item.onSelect();
                    }    
                }
            })
        }
        check(globalData.model.boardState.idToHanditems);
        check(globalData.model.boardState.idToButtons);
    }

    /*public*/ Board.prototype.draw = function() {        
        this.ctxBoard.clearRect(0, 0, this.ctxBoard.canvas.width, this.ctxBoard.canvas.height);
        this.drawFields();
        this.drawUnits();
        this.drawHand();
        this.drawButtons();
        this.drawModalDialog();
    };    
    
    /*private*/ Board.prototype.drawFields = function() {
        for ( var f in globalData.model.boardState.corToFields) {
            globalData.model.boardState.corToFields[f].draw(this.ctxBoard, globalData.model.boardState.showCoordinates);
        }
    }
    /*private*/ Board.prototype.drawUnits = function() {
        // units- z-level:0
        for ( var f in globalData.model.boardState.idToUnits) {
            var unitToDraw = globalData.model.boardState.idToUnits[f];
            unitToDraw.draw0(this.ctxBoard);
        }
        // units- z-level:1
        for ( var f in globalData.model.boardState.idToUnits) {
            var unitToDraw = globalData.model.boardState.idToUnits[f];
            unitToDraw.draw1(this.ctxBoard);
        }
        // units- z-level:2
        for ( var f in globalData.model.boardState.idToUnits) {
            var unitToDraw = globalData.model.boardState.idToUnits[f];
            unitToDraw.draw2(this.ctxBoard);
        }
    }
    /*private*/ Board.prototype.drawHand = function() {
        this.ctxBoard.beginPath();
        this.ctxBoard.fillStyle = "#dddddd";
        this.ctxBoard.fillRect(0, Constants.size.height*10*.8, Constants.size.width*10.5, .95*Constants.size.height);
        var x = 3;
        var y = Constants.size.height*10*.8+5;
        for ( var f in globalData.model.boardState.idToHanditems) {
            var handitemToDraw = globalData.model.boardState.idToHanditems[f];
            handitemToDraw.draw(this.ctxBoard, x, y);
            x += Constants.size.width*.8+4;
        }
        if(x == 3) {
            this.ctxBoard.beginPath();
            this.ctxBoard.font = ""+parseInt(.267*Constants.size.height)+"px Arial";
            this.ctxBoard.fillStyle = "black";
            this.ctxBoard.fillText("No units at hand.",x,y + (.5*Constants.size.height));
        }

    }
    /*private*/ Board.prototype.drawButtons = function() {
        var x = 3;
        var y = Constants.size.height*10*.8 + .95*Constants.size.height + 10;
        var thiz = this;
        $.each(sortById(globalData.model.boardState.idToButtons), function(buttonId, buttonToDraw) {
            if(!buttonToDraw.hidden) {
                buttonToDraw.draw(thiz.ctxBoard, x, y);
                x += buttonToDraw.getWidth() + .0667*Constants.size.width;
            }
        });

    }
    /*private*/ Board.prototype.drawModalDialog = function() {
        if(typeof globalData.model.modalDialogState !== 'undefined' && globalData.model.modalDialogState != null) {
            globalData.model.modalDialogState.draw(this.ctxBoard);
        }
    }
    
    
    /**
     * returns a Field object which is located at pos (x,y)
     */
    /*private*/Board.prototype.getFieldByPos = function(pos) {
        // x,y base coordinate
        var hexPosY = Math.floor(pos.y / (Constants.size.height * 0.75));
        var hexPosX = Math.floor(pos.x / Constants.size.width);
        // odd or even row?
        var rowSelector = hexPosY % 2;

        // x,y rel to current element
        var posYRel = pos.y - hexPosY * Constants.size.height * 0.75;
        var posXRel = pos.x - hexPosX * Constants.size.width;

        switch (rowSelector) {
        case 0:
            // odd row
            if (posYRel < Constants.size.height / 4) {
                // the top part (looks like a roof ^ )
                var s = posXRel / (Constants.size.width / 2);
                var r = posYRel / (Constants.size.height / 4);
                if (0 <= r && s <= 1 && r + s <= 1) {
                    // left of the roof (belongs to previous row and column)
                    hexPosX--;
                    hexPosY--;
                } else {
                    s = posYRel / (Constants.size.height / 4);
                    r = posXRel / (Constants.size.width / 2) - s - 1;
                    if (0 <= r && s <= 1 && r + s <= 1) {
                        // right of the roof (belongs to previous row)
                        hexPosY--;
                    }
                    // no change for "under the roof"
                }
            }
            break;
        case 1:
            // even row
            if (posYRel > Constants.size.height / 4) {
                // lower part (divided in the middle)
                if (posXRel < Constants.size.width / 2) {
                    // left part (belongs to previous hex)
                    hexPosX--;
                }
            } else {
                // upper part (looks like a "v")
                var s = posXRel / (Constants.size.width / 2);
                var r = posYRel / (Constants.size.height / 4) - s;
                if (0 <= r && s <= 1 && r + s <= 1) {
                    // left lower part of the v
                    hexPosX--;
                } else {
                    var s = (posXRel - Constants.size.width) / (Constants.size.width / 2) * -1;
                    var r = (posYRel / (Constants.size.height / 4)) - s;
                    if (!(0 <= r && s <= 1 && r + s <= 1)) {
                        // middle part v (or not the right lower part)
                        hexPosY--;
                    }
                }
            }
            break;
        }

        if (globalData.model.boardState.corToFields.hasOwnProperty(hexPosX + ":" + hexPosY)) {
            return globalData.model.boardState.corToFields[hexPosX + ":" + hexPosY];
        }
        return null;
    };
    
    return function(elementId) {
        var board = new Board(elementId);    
        this.draw = function() {
            board.draw();
        }
        this.init = function() {
            board.init();
        }
    };
    
});