
function View (unitSize, boardStartX, boardStartY, windowWidth, windowHeight) {
  this.unitSize = unitSize;
  this.boardStartX = boardStartX;
  this.boardStartY = boardStartY;
  this.windowWidth = windowWidth;
  this.windowHeight = windowHeight;
}

function Render (outputter, view) {
  this.outputter = outputter;
  this.view = view;
}


Render.prototype.draw = function(board) {
  this.outputter.start();
  assert(board.pieces.length > 0);
  var swappable = new Array(); // draw them last since they have a diff border
  for (var i = 0; i < board.pieces.length; i++) {
    if (board.pieces[i].swappable) {
      swappable.push(board.pieces[i]);
    } else {
      this._drawPiece(board.pieces[i]);
    }  
  }
  for (var i = 0; i < swappable.length; i++) {
    this._drawPiece(swappable[i]);
  }
  if (this.view.boardStartX > 0) {
    this.outputter.drawEmpty(0, 0, this.view.boardStartX, this.view.windowHeight);
  }
  if (this.view.boardStartY > 0) {
    this.outputter.drawEmpty(0, 0, this.view.windowWidth, this.view.boardStartY);
  }
  if (this.view.boardStartX + board.x * this.view.unitSize < this.view.windowWidth) {
    this.outputter.drawEmpty(this.view.boardStartX + board.x * this.view.unitSize, 0, this.view.windowWidth - this.view.boardStartX - board.x * this.view.unitSize, this.view.windowHeight);
  }
  if (this.view.boardStartY + board.y * this.view.unitSize < this.view.windowHeight) {
    this.outputter.drawEmpty(0, this.view.boardStartY + board.y * this.view.unitSize, this.view.windowWidth, this.view.windowHeight - this.view.boardStartY - board.y * this.view.unitSize);
  }
  this.outputter.flush();
} 

Render.prototype._drawPiece = function(piece) {
    var x = this.view.boardStartX + piece.start[HORIZONTAL].top * this.view.unitSize / piece.start[HORIZONTAL].bot;
    var y = this.view.boardStartY + piece.start[VERTICAL].top * this.view.unitSize / piece.start[VERTICAL].bot;
    var xlen = piece.x.top * this.view.unitSize / piece.x.bot;
    var ylen = piece.y.top * this.view.unitSize / piece.y.bot;
    
    if (x + xlen < 0 || y + ylen < 0 || x > this.view.windowWidth || y > this.view.windowHeight) 
      return;
    
    
    if (x + xlen > this.view.windowWidth) xlen = this.view.windowWidth - x;
    if (y + ylen > this.view.windowHeight) ylen = this.view.windowHeight - y;
    if (x < 0) {
      xlen += x;
      x = 0;
    }
    if (y < 0) {
      ylen += y;
      y = 0;
    }
    
    this.outputter.drawElement(x, y, xlen, ylen, 
    	piece.color, 
    	piece.swapped, 
    	piece.numLinksToBorders == 4, 
    	piece.captured > 0, 
    	piece.swappable);
    	
}

toTest.push(Render);


function MockOutput(view) {
  this.view = view;
  this.pixels = new Array();
  for (var i = 0; i < this.view.windowHeight; i++) {
    this.pixels[i] = new Array();
  }
}

MockOutput.prototype.drawElement = function(x, y, xlen, ylen, color, swapped, numConnections) {
  assert(this.view);
  assert(x >= 0 && y >= 0 && xlen < this.view.windowWidth && ylen < this.view.windowHeight);
  for (var j = y; j < ylen; j++) {
    for (var i = x; i < xlen; i++) {  
        this.pixels[j][i] = color + 1;     
    }
  }
}

MockOutput.prototype.drawEmpty = function(x, y, xlen, ylen) {
}


MockOutput.prototype.flush = function() {
}

MockOutput.prototype.start = function() {
}

Render.prototype.test = function() {
  var view = new View(5, 20, 20, 50, 50);
  var mockOutput = new MockOutput(view);
  var board = new Board(6, 6);
  board.build();
  var render = new Render(mockOutput, view);
  render.draw(board);
}