dojo.provide("acf.Board"); dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("dojo.dnd.Source"); dojo.require("dijit._Widget"); dojo.require("dijit._Templated"); dojo.declare("acf.Board",[dijit._Widget, dijit._Templated], { constructor: function() { this._getCSSRules(); }, templatePath: dojo.moduleUrl("acf","resources/Board.html"), widgetsInTemplate: true, // Board orientation (l2h - Low numbers at top, h2l - High numbers at top) orientation: 'h2l', // Number of rows to display (default to standard 64 square board) rows: 8, // Number of columns to display (should be same as rows) cols: null, // Playable squares (l - light, d - dark, * - any, other - none) playable: '', // Size of squares (default to 6 em) sqSize: 5, // Units for square size (use em because we're lazy) sqSizeUnit: 'em', // Increment to adjust the board size by (default to .5 em) sqAdjust: 0.5, // Background image to use for dark squares darkImg: dojo.moduleUrl("acf","resources/images/dark.gif"), // Background image to use for light squares lightImg: dojo.moduleUrl("acf","resources/images/light.gif"), // Background image to use for the bank bankImg: dojo.moduleUrl("acf","resources/images/dark.gif"), // Show numbers on playable squares showNumbers: 'on', // CSS Sheet to modify cssSheetId: -1, // CSS Rule that applies to .game cssGameRule: -1, // CSS Rule that applies to .board cssBoardRule: -1, // CSS Rule that applies to .board .row cssRowRule: -1, // CSS Rule that applies to .board .row .square cssSquareRule: -1, // CSS Rule that applies to .board .row .square .dark cssDarkRule: -1, // CSS Rule that applies to .board .row .square .light cssLightRule: -1, // CSS Rule that applies to .board .row .square .playable .num cssNumRule: -1, // CSS Rule that applies to .game .menu cssMenuRule: -1, // CSS Rule that applies to .game .toolbar cssToolRule: -1, // CSS Rule that applies to .game .title cssTitleRule: -1, // CSS Rule that applies to .game .bank cssBankRule: -1, // CSS Rule that applies to .game .moves cssMovesRule: -1, // CSS Rule that applies to .game .pdn cssPdnRule: -1, // Dummy accept function to test if DND is accepted (accept everything) _isAccepted: function(p_source,p_nodes) { return true; }, // Dummy drop function to be overridden by subclass _doDrop: function(p_source,p_nodes,p_copy,p_target) { if(dojo.dnd.manager().target !== this) { return; } }, // Determines if a square should have "playable" status _isPlayable: function(p_type) { // If playable is * return true, else compare playable to the passed value return (this.playable == '*') ? true : (p_type == this.playable); }, // Loop through stylesheets looking for board.css // Save the indexes for rules we want to modify _getCSSRules: function() { var sheets = document.styleSheets; // Break as soon as we find the styleSheet to cut down processing for(var i = 0; i < sheets.length && this.cssSheetId < 0; i++) { if(sheets[i].href.indexOf('board.css') > -1) { this.cssSheetId = i; var rules = (dojo.isIE) ? sheets[i].rules : sheets[i].cssRules; for(var j = 0; j < rules.length; j++) { if(rules[j].selectorText == '.game') { this.cssGameRule = j; } if(rules[j].selectorText == '.game .menu') { this.cssMenuRule = j; } if(rules[j].selectorText == '.game .toolbar') { this.cssToolRule = j; } if(rules[j].selectorText == '.game .title') { this.cssTitleRule = j; } if(rules[j].selectorText == '.game .bank') { this.cssBankRule = j; } if(rules[j].selectorText == '.game .moves') { this.cssMovesRule = j; } if(rules[j].selectorText == '.game .pdn') { this.cssPdnRule = j; } if(rules[j].selectorText == '.board') { this.cssBoardRule = j; } if(rules[j].selectorText == '.board .row') { this.cssRowRule = j; } if(rules[j].selectorText == '.board .square') { this.cssSquareRule = j; } if(rules[j].selectorText == '.board .square .dark') { this.cssDarkRule = j; } if(rules[j].selectorText == '.board .square .light') { this.cssLightRule = j; } if(rules[j].selectorText == '.board .square .playable .num') { this.cssNumRule = j; } } } } }, _resize: function() { var rules = (dojo.isIE) ? document.styleSheets[this.cssSheetId].rules : document.styleSheets[this.cssSheetId].cssRules; var d = rules[this.cssDarkRule].style; var l = rules[this.cssLightRule].style; d.backgroundImage = 'url('+this.darkImg+')'; l.backgroundImage = 'url('+this.lightImg+')'; var b = rules[this.cssBoardRule].style; var r = rules[this.cssRowRule].style; var s = rules[this.cssSquareRule].style; b.width = String(this.sqSize*this.rows)+this.sqSizeUnit; b.height = String(this.sqSize*this.cols)+this.sqSizeUnit; r.width = String(this.sqSize*this.rows)+this.sqSizeUnit; r.height = String(this.sqSize)+this.sqSizeUnit; s.width = String(this.sqSize)+this.sqSizeUnit; s.height = String(this.sqSize)+this.sqSizeUnit; this.bank.style.width = s.width; var w = this.board.offsetLeft + this.board.offsetWidth; if(dojo.isIE) { this.right.style.position = 'relative'; } else { this.right.style.left = w; } w += this.right.offsetWidth; var h = this.board.offsetTop + this.board.offsetHeight; if(dojo.isIE) { h+=50; } this.pdn.style.top = h; this.controls.style.top = h + this.pdn.offsetHeight; //this.left.domNode.style.height = b.height; this.left.style.height = b.height; this.right.style.height = b.height; this.toolbar.style.width = w; this.menu.style.width = w; this.title.style.width = w; this.pdn.style.width = w; this.controls.style.width = w; }, makeBigger: function() { var b = (this._board) ? this._board : this; b.sqSize = b.sqSize + b.sqAdjust; b._resize(); }, makeSmaller: function() { var b = (this._board) ? this._board : this; b.sqSize = b.sqSize - b.sqAdjust; if(b.sqSize <= 0) { b.sqSize = b.sqAdjust; } b._resize(); }, toggleNumbers: function(p_value) { var b = (this._board) ? this._board : this; var rules = (dojo.isIE) ? document.styleSheets[b.cssSheetId].rules : document.styleSheets[b.cssSheetId].cssRules; var n = rules[b.cssNumRule].style; if(p_value == 'off') { n.display = 'none'; } else if(p_value == 'on') { n.display = 'block'; } else { n.display = (n.display == 'none') ? 'block' : 'none'; } }, // Make the private function available to public (this will be overwritten) flipBoard: function() { var b = (this._board) ? this._board : this; b._flipBoard(); }, _flipBoard: function() { var b = (this._board) ? this._board : this; b.orientation = (this.orientation == 'h2l') ? 'l2h' : 'h2l'; b._createBoard(); }, _createBoard: function() { var cnt = 1; var play_cnt = this.rows * this.cols; // _isPlayable('x') will return true only if everything is playable // Otherwise cut playable in half if(!this._isPlayable('x')) { play_cnt = play_cnt/2; } if(this.board.hasChildNodes()) { dojo.empty(this.board); } if(this.orientation == 'h2l') { cnt = play_cnt * -1; } for(var i = 0; i < this.rows; i++){ var r = dojo.create('div'); dojo.addClass(r,'row'); for(var j = 0; j < this.cols; j++) { var s = dojo.create('div'); dojo.addClass(s,'square'); // 0+0 = l, 0+1 = d, 1+0 = d, 1+1 = l var c = ((i%2 + j%2) == 1) ? 'dark' : 'light'; var t = dojo.create('div'); dojo.addClass(t,c); if(this._isPlayable(c.substr(0,1))) { // get current square number (negatives if high to low so convert) var num = Math.abs(cnt); cnt++; // Mark as playable dojo.addClass(t,'playable'); // Make DND enabled var x = new dojo.dnd.Source(t); // Set the acceptance method x.checkAcceptance = this._isAccepted; // Set square number to a variable we can reference later x.square = num; x.board = this; dojo.connect(x,"onDndDrop",this._doDrop); // Add an empty piece div with attachpoint of square_XX var ap = 'square_'+num; var p = dojo.create('div',{dojoAttachPoint: ap, value: '.'}); dojo.addClass(p, 'piece'); //TODO only if mode allows // Make Dnd enabled dojo.addClass(p, 'dojoDndItem'); p.dnd = x; dojo.place(p,t); // Add a numeric value to the square dojo.query(dojo.create('div',{innerHTML: num})).addClass('num').place(t); } dojo.place(t,s); dojo.place(s,r); } dojo.place(r,this.board); } // Attach the 'square_XX' objects to the board this._attachTemplateNodes(this.board); // Finally set the size accordingly this._resize(); }, // Stub to create the bank section _createBank: function() { }, // Create a simple toolbar _createToolbar: function() { var t = this.toolbar; if(t.hasChildNodes()) { dojo.empty(t); } if(!dojo.isIE) { t.style.cssFloat = 'left'; } var b = dojo.create('div'); dojo.addClass(b,'icon'); b.style.backgroundImage = 'url('+dojo.moduleUrl("acf","resources/icons/up_16.png")+')'; dojo.attr(b,'title','Larger'); b._board = this; dojo.connect(b,"onclick",this.makeBigger); dojo.place(b,t); // b = dojo.create('div'); dojo.addClass(b,'icon'); b.style.backgroundImage = 'url('+dojo.moduleUrl("acf","resources/icons/down_16.png")+')'; dojo.attr(b,'title','Smaller'); b._board = this; dojo.connect(b,"onclick",this.makeSmaller); dojo.place(b,t); // b = dojo.create('div'); dojo.addClass(b,'icon'); b.style.backgroundImage = 'url('+dojo.moduleUrl("acf","resources/icons/arrow_undo.png")+')'; dojo.attr(b,'title','Flip Board'); b._board = this; dojo.connect(b,"onclick",this.flipBoard); dojo.place(b,t); // b = dojo.create('div'); dojo.addClass(b,'icon'); b.style.backgroundImage = 'url('+dojo.moduleUrl("acf","resources/icons/anchor.png")+')'; dojo.attr(b,'title','Toggle Numbers'); b._board = this; dojo.connect(b,"onclick",this.toggleNumbers); dojo.place(b,t); }, postCreate: function() { // Have to do this here because constructor doesn't read html yet if(!this.cols) { this.cols = this.rows; } this._createBoard(); this.toggleNumbers(this.showNumbers); } });