/* A GoDisplayBoard - the job of this object will be
   two-fold: it houses the event handler that translates
   mouse clicks into go stone coordinates (<a-s><a-s>),
   and it contains the SVGBoard object.

   It receives the id of the node it is attached to and a 
   boardsize which will be one of 19, 12, 7

*/

//Create my namespace
var net;
if(!net) {
	 net = {};
} else if (typeof net != "object") {
  throw new Error("net already exists and is not an object");
}

if(!net.gonote) {
		net.gonote = {};
} else if(typeof net.gonote != "object") {
  throw new Error("net.gonote already exists and is not an object");
}

if(net.gonote.displayboard) {
	throw new Error("net.gonote already exists");
}

net.gonote.displayboard = {};

net.gonote.displayboard.GoDisplayBoard = net.gonote.util.defineClass(
	{

	name: "GoDisplayBoard",
	construct: function(myNodeId, boardSize) {

		this.myNodeId = myNodeId; //Receives the id of the node that it will be tied to
		this.myNode = document.getElementById(myNodeId); //get the node
		this.boardSize = boardSize; //This is a 19x19 or 13x13 board

		//The svg element owned by this 
		this.svgElement = null;

		//This is the width and height of our tag and board
		//The node passed to us may have to be adjusted to be square and
		//have a width and height as determined in init function
		//This will be readjusted on a resize event
		this.dimension = 0; 

		//Once the boardSize has been chosen, this is our unit of intersection measure
		this.unit = 0;

		//Here are the coordinates of the intersections of the board in terms of screen real estate (not SVG viewport units)
		//Calculated in init. This will be readjusted on a resize event
		this.i_coords = [];
		this.coords_map = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];

		//This is the array of possible pixel sizes for our board
		//Used when determining a pixel width and height for the board. See init function below
		this.pixel_sizes = net.gonote.util.mapArray([41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7], function(mod) { return mod * boardSize });  
	},
	methods: {
		 //The init function fixes the size of the node, and creates an svgElement
		 init: function() {

		       var myNode = this.myNode;
		       var height = myNode.offsetHeight;
		       var width = myNode.offsetWidth;
			var pixel_sizes = this.pixel_sizes;

		       //Calculate an element size we can work with and make it so
		       var final_dimension = 0;

		       //Make sure it's square, and be nice
		       if(height != width) {
				 if(height < width) { width = height; } else { height = width;}
			}
			for(var i = 0; i < pixel_sizes.length;i++) {
			      if(height >= pixel_sizes[i]) {
				final_dimension = pixel_sizes[i];
				break;
			      }
			}

			this.unit = final_dimension / this.boardSize;
			this.dimension = final_dimension;

			//Set this size in the style
			myNode.style.height = myNode.style.width = final_dimension + "px";
			
			//Make sure other style attributes are correct. Just make them so
			myNode.style.position = "absolute";
			myNode.style.padding = "0px";

			//Init the SVGBoard
			this.svgElement = new net.gonote.displayboard.SVGBoard(myNode, this.boardSize, final_dimension);


/*
			//Now initialize move stack
			this.moveStack = new net.gonote.model.MoveStack(this, this.svgElement);
*/
			net.gonote.util.log("stack: " + this.moveStack);


			//Calculate the coordinates of the intersections
			var unit = this.dimension / this.boardSize;
			var coord = ((unit - 1) / 2) + 1;
			for(var i = 0;i < this.boardSize;i++) {
				this.i_coords[i] = coord;
				coord += unit;
			}


//			net.gonote.util.log("Init i_coords: " + this.i_coords);

		},


		//In order to get x and y perfectly, we have to assume that border is 
		//set in element style, and that it is set in pixels
		//Get the x offset to the beginning of content
		
		getXOffset: function(/*Node in question*/elem) {
			var x = 0;
			
			if(!elem.style.borderLeftWidth) {
				if(!elem.style.borderWidth) {
					//assume 0 border
				} else {
					x = parseInt(elem.style.borderWidth);
				}
			} else {
				x = parseInt(elem.style.borderLeftWidth);
			}

//			net.gonote.util.log("Border width check set x to: " + x);

			while(elem) {
				x += elem.offsetLeft;
				elem = elem.offsetParent;
			}

//			net.gonote.util.log("Parent offset check set x to: " + x);

			x -= window.pageXOffset;

//			net.gonote.util.log("Page offset check set x to: " + x);

			
			return x;
                },
		getYOffset: function(/*Node in question */elem) {

			var y = 0;

			if(!elem.style.borderTopWidth) {
				if(!elem.style.borderWidth) {
					//assume 0 border
				} else {
					y = parseInt(elem.style.borderWidth);
				}
			} else {
				y = parseInt(elem.style.borderTopWidth);
			}

//			net.gonote.util.log("Border width check set y to: " + y);


			while(elem) { 
				y += elem.offsetTop;
				elem = elem.offsetParent;
			}
//			net.gonote.util.log("Parent offset check set y to: " + y);

			y -= window.pageYOffset;

//			net.gonote.util.log("Page offset check set y to: " + y);


			return y;
		},
			
		getMoveX: function(evt) {
				var moveXIndex = "";
				var myX = evt.clientX;

				myX -= this.getXOffset(this.myNode);
				if(myX % this.unit > 0) {
					moveXIndex = this.coords_map[Math.floor(myX / this.unit)];
				} else {
					moveXIndex = this.coords_map[Math.floor(myX / this.unit) - 1];
				}
			return(moveXIndex);
		},
		getMoveY: function(evt) {
				var moveYIndex = "";
				var myY = evt.clientY;

				//Where are we?
				myY -= this.getYOffset(this.myNode);
				if(myY % this.unit > 0) {
					moveYIndex = this.coords_map[Math.floor(myY / this.unit)];
				} else {
					moveYIndex = this.coords_map[Math.floor(myY / this.unit) - 1];
				}

			return(moveYIndex);
		},					
	
		addMove: function(/*Move*/move) { this.svgElement.addMove(move); },
		deleteMove: function(/*Move*/move) { this.svgElement.deleteMove(move); },
		suppressNumbers: function() { this.svgElement.suppressNumbers(); },
		liberateNumbers: function() { this.svgElement.liberateNumbers(); },
		highlightMove: function(/*Move*/move) { this.svgElement.highlightMove(move); }

	}
	
});

//What do we want out of the SVGBoard. One is the board grid and the other is a group in which to put the moves
//We also need it to addMove, deleteMove suppressMoveNumber and liberateMoveNumber. For that, it will have to interpret the move
//coordinates (<a-s><a-s>) into an intersection location.
//Because stones and numbers are intimitely associated, each pair will go into its own group. The group will have
//a name, which will be the identifier of the move.

net.gonote.displayboard.SVGBoard = net.gonote.util.defineClass(
	{

		name: "SVGBoard",
		construct: function(/*DOM node*/parentNode, /*int*/gridDimension, /*int*/pixDim) {

			this.parentNode = parentNode;
			this.boardDimension = 0;
			this.gridDimension = gridDimension;
			this.i_coords = null;
			this.r = 13; //a nice number. Remember 13 + 13 + 1 = 27
			if(gridDimension == 13) {
				this.boardDimension = 351;
				this.i_coords = { a:14, b:41, c:68, d:95, e:122, f:149, g:176, h:203, i:230, j:257, k:284, l:311, m:338 };
			} else {
				this.boardDimension = 513;
				this.i_coords = { a:14, b:41, c:68, d:95, e:122, f:149, g:176, h:203, i:230, j:257, k:284, l:311, m:338, n:365, o:392, p:419, q:446, r:473, s:500};
			} 			


			//Make an svg node. Make its viewport 494 by 494, to be evenly divisible by 13 and 19 
			this.svgNode = SVG.makeCanvas("canvas", pixDim, pixDim, this.boardDimension, this.boardDimension);
			var board = document.createElementNS(SVG.ns, "g");
			var path = document.createElementNS(SVG.ns, "path");

	//conditionalize for 13 or 19

			 if(gridDimension == 19) {

			 			path.setAttribute("d", "M14 14 L500 14 L500 500 L14 500 L14 14 M41 14 L41 500 M68 14 L68 500 M95 14 L95 500 M122 14 L122 500 M149 14 L149 500 M176 14 L176 500 M203 14 L203 500 M230 14 L230 500 M257 14 L257 500 M284 14 L284 500 M311 14 L311 500 M338 14 L338 500 M365 14 L365 500 M392 14 L392 500 M419 14 L419 500 M446 14 L446 500 M473 14 L473 500 M473 14 L473 500 M14 41 L500 41 M14 68 L500 68 M14 95 L500 95 M14 122 L500 122 M14 149 L500 149 M14 176 L500 176 M14 203 L500 203 M14 230 L500 230 M14 257 L500 257 M14 284 L500 284 M14 311 L500 311 M14 338 L500 338 M14 365 L500 365 M14 392 L500 392 M14 419 L500 419 M14 446 L500 446 M14 473 L500 473 M14 473 L500 473 Z");

						path.setAttribute("fill", "white");
						path.setAttribute("stroke", "black");
						path.setAttribute("stroke-width", "1");
						board.appendChild(path);				  
						
						var hdcpPoint1 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint1.setAttribute("cx", "95");
						hdcpPoint1.setAttribute("cy", "95");
						hdcpPoint1.setAttribute("r", "3");
						hdcpPoint1.setAttribute("stroke", "black");
						hdcpPoint1.setAttribute("stroke-width", "1");
						hdcpPoint1.setAttribute("fill", "black");
						board.appendChild(hdcpPoint1);

						var hdcpPoint2 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint2.setAttribute("cx", "95");
						hdcpPoint2.setAttribute("cy", "257");
						hdcpPoint2.setAttribute("r", "3");
						hdcpPoint2.setAttribute("stroke", "black");
						hdcpPoint2.setAttribute("stroke-width", "1");
						hdcpPoint2.setAttribute("fill", "black");
						board.appendChild(hdcpPoint2);

						var hdcpPoint3 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint3.setAttribute("cx", "95");
						hdcpPoint3.setAttribute("cy", "419");
						hdcpPoint3.setAttribute("r", "3");
						hdcpPoint3.setAttribute("stroke", "black");
						hdcpPoint3.setAttribute("stroke-width", "1");
						hdcpPoint3.setAttribute("fill", "black");
						board.appendChild(hdcpPoint3);

						var hdcpPoint4 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint4.setAttribute("cx", "257");
						hdcpPoint4.setAttribute("cy", "95");
						hdcpPoint4.setAttribute("r", "3");
						hdcpPoint4.setAttribute("stroke", "black");
						hdcpPoint4.setAttribute("stroke-width", "1");
						hdcpPoint4.setAttribute("fill", "black");
						board.appendChild(hdcpPoint4);

						var hdcpPoint5 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint5.setAttribute("cx", "257");
						hdcpPoint5.setAttribute("cy", "257");
						hdcpPoint5.setAttribute("r", "3");
						hdcpPoint5.setAttribute("stroke", "black");
						hdcpPoint5.setAttribute("stroke-width", "1");
						hdcpPoint5.setAttribute("fill", "black");
						board.appendChild(hdcpPoint5);

						var hdcpPoint6 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint6.setAttribute("cx", "257");
						hdcpPoint6.setAttribute("cy", "419");
						hdcpPoint6.setAttribute("r", "3");
						hdcpPoint6.setAttribute("stroke", "black");
						hdcpPoint6.setAttribute("stroke-width", "1");
						hdcpPoint6.setAttribute("fill", "black");
						board.appendChild(hdcpPoint6);

						var hdcpPoint7 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint7.setAttribute("cx", "419");
						hdcpPoint7.setAttribute("cy", "95");
						hdcpPoint7.setAttribute("r", "3");
						hdcpPoint7.setAttribute("stroke", "black");
						hdcpPoint7.setAttribute("stroke-width", "1");
						hdcpPoint7.setAttribute("fill", "black");
						board.appendChild(hdcpPoint7);

						var hdcpPoint8 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint8.setAttribute("cx", "419");
						hdcpPoint8.setAttribute("cy", "257");
						hdcpPoint8.setAttribute("r", "3");
						hdcpPoint8.setAttribute("stroke", "black");
						hdcpPoint8.setAttribute("stroke-width", "1");
						hdcpPoint8.setAttribute("fill", "black");
						board.appendChild(hdcpPoint8);

						var hdcpPoint9 = document.createElementNS(SVG.ns, "circle");
						hdcpPoint9.setAttribute("cx", "419");
						hdcpPoint9.setAttribute("cy", "419");
						hdcpPoint9.setAttribute("r", "3");
						hdcpPoint9.setAttribute("stroke", "black");
						hdcpPoint9.setAttribute("stroke-width", "1");
						hdcpPoint9.setAttribute("fill", "black");
						board.appendChild(hdcpPoint9);

			} else if(this.gridDimension == 13) {


			  path.setAttribute("d", "M14 14 L351 14 L351 351 L14 351 L14 14 M41 14 L41 351 M68 14 L68 351 M95 14 L95 351 M122 14 L122 351 M149 14 L149 351 M176 14 L176 351 M203 14 L203 351 M230 14 L230 351 M257 14 L257 351 M284 14 L284 351 M311 14 L311 351 M338 14 L338 351 M14 41 L351 41 M14 68 L351 68 M14 95 L351 95 M14 122 L351 122 M14 149 L351 149 M14 176 L351 176 M14 203 L351 203 M14 230 L351 230 M14 257 L351 257 M14 284 L351 284 M14 311 L351 311 M14 338 L351 338 Z");

			  path.setAttribute("fill", "white");
			  path.setAttribute("stroke", "black");
			  path.setAttribute("stroke-width", "1");
			  board.appendChild(path);

			  var hdcpPoint1 = document.createElementNS(SVG.ns, "circle");
			  hdcpPoint1.setAttribute("cx", "95");
			  hdcpPoint1.setAttribute("cy", "95");
			  hdcpPoint1.setAttribute("r", "3");
			  hdcpPoint1.setAttribute("stroke", "black");
			  hdcpPoint1.setAttribute("stroke-width", "1");
			  hdcpPoint1.setAttribute("fill", "black");
			  board.appendChild(hdcpPoint1);

			  var hdcpPoint2 = document.createElementNS(SVG.ns, "circle");
			  hdcpPoint2.setAttribute("cx", "95");
			  hdcpPoint2.setAttribute("cy", "257");
			  hdcpPoint2.setAttribute("r", "3");
			  hdcpPoint2.setAttribute("stroke", "black");
			  hdcpPoint2.setAttribute("stroke-width", "1");
			  hdcpPoint2.setAttribute("fill", "black");
			  board.appendChild(hdcpPoint2);

			  var hdcpPoint4 = document.createElementNS(SVG.ns, "circle");
			  hdcpPoint4.setAttribute("cx", "257");
			  hdcpPoint4.setAttribute("cy", "95");
			  hdcpPoint4.setAttribute("r", "3");
			  hdcpPoint4.setAttribute("stroke", "black");
			  hdcpPoint4.setAttribute("stroke-width", "1");
			  hdcpPoint4.setAttribute("fill", "black");
			  board.appendChild(hdcpPoint4);

			  var hdcpPoint5 = document.createElementNS(SVG.ns, "circle");
			  hdcpPoint5.setAttribute("cx", "257");
			  hdcpPoint5.setAttribute("cy", "257");
			  hdcpPoint5.setAttribute("r", "3");
			  hdcpPoint5.setAttribute("stroke", "black");
			  hdcpPoint5.setAttribute("stroke-width", "1");
			  hdcpPoint5.setAttribute("fill", "black");
			  board.appendChild(hdcpPoint5);

		}

			var moves = document.createElementNS(SVG.ns, "g");
			
			this.svgNode.appendChild(board);
			
			this.moves = moves;

			this.svgNode.appendChild(moves);

			this.parentNode.appendChild(this.svgNode);
		},

		methods: {
			 addMove: function(/* Move object */move) { 

				//Create an envelope for our submission
				var envelope = document.createElementNS(SVG.ns, "g");
				envelope.setAttribute("name", move.getName());

//				net.gonote.util.log("move color: " + move.getColor().toString());

				//Get our x and y
				var x = this.i_coords[move.getXIndex()];
				var y = this.i_coords[move.getYIndex()];

				var mRep = document.createElementNS(SVG.ns, "circle");
				
				mRep.setAttribute("cx", x);
				mRep.setAttribute("cy", y);
				mRep.setAttribute("r", this.r);
				mRep.setAttribute("stroke", "black");
				mRep.setAttribute("stroke-width", "1");
				if(move.getColor() == net.gonote.move.Stone.BLACK) {
					mRep.setAttribute("fill", "black");
				} else {
					mRep.setAttribute("fill", "white");
				}

				var moveLabel = move.getLabel();

				var label = document.createElementNS(SVG.ns, "text");
				if(moveLabel.length == 1) {
					label.setAttribute("x", x - 4);
				} else if(moveLabel.length == 2) {
					label.setAttribute("x", x - 8);
				} else if(moveLabel.length == 3) {
					label.setAttribute("x", x - 12);
				}
				label.setAttribute("y", y + 6);
				label.setAttribute("font-family", "sans-serif");
				label.setAttribute("font-size", "14");
				
				if(move.getColor() == net.gonote.move.Stone.BLACK) {
					label.setAttribute("fill", "white");
				} else {
					label.setAttribute("fill", "black");
				}

				label.appendChild(document.createTextNode(moveLabel));

				envelope.appendChild(mRep);
				envelope.appendChild(label);
				this.moves.appendChild(envelope);
			},
			deleteMove: function(/* Move object */move) { 

				var moveName = move.getName();
				var moveElement = null;
				var moveElements = this.moves.getElementsByTagName("g");
				for(var i = 0;i < moveElements.length;i++) {
					if(moveElements[i].getAttribute("name") == moveName) {
						moveElement = moveElements[i];
						this.moves.removeChild(moveElement);
			//			moveElements[i].setAttribute("visibility", "hidden");
						break;
					}
				}
				
			},
			suppressNumbers: function() {  
				
			},
			liberateNumbers: function() { 
			},
			highlightMove: function(/*Move*/move) { 
			}
		}
	});

net.gonote.displayboard.report = function() {

	net.gonote.util.log("board loaded");
} 

