var BOARD_WIDTH = 14;
var BOARD_HEIGHT = 28;
var BLOCK_WIDTH = 24;
var BLOCK_HEIGHT = 24;

var PIECE_1 = new Array(new Array("1","1"),
			new Array("1","1"));

var PIECE_2 = new Array(new Array("2"),
			new Array("2"),
			new Array("2"),
			new Array("2"));

var PIECE_3 = new Array(new Array("0","3","3"),
			new Array("3","3","0"));

var PIECE_4 = new Array(new Array("4","4","0"),
			new Array("0","4","4"));

var PIECE_5 = new Array(new Array("5","0"),
			new Array("5","0"),
			new Array("5","5")
		       );

var PIECE_6 = new Array(new Array("0","6","0"),
			new Array("6","6","6")
		       );

var PIECE_7 = new Array(new Array("0","7"),
			new Array("0","7"),
			new Array("7","7")
		       );
var PIECE_TYPES = new Array(
  new Array(PIECE_1,"1"),
  new Array(PIECE_2,"2"),
  new Array(PIECE_3,"3"),
  new Array(PIECE_4,"4"),
  new Array(PIECE_5,"5"),
  new Array(PIECE_6,"6"),
  new Array(PIECE_7,"6")
);
var SCORE = 0;

var SPEED = 500;

function rand(start,end){
  return Math.floor(Math.random()*end)+start;
}

function Board(){
  this.blocks = new Array();

  this.create_blank = function(){
    var board = new Array();
    for(var y = 0; y < BOARD_HEIGHT;y++){
      var row = new Array();
      for(var x = 0; x < BOARD_WIDTH;x++){
	row.push("0");
      }
      board.push(row);
    }
    return board;
  };

  this.print_layout = function(){
    var out = "";
    for(var y = 0;y < BOARD_HEIGHT;y++){
      for(var x = 0; x< BOARD_WIDTH;x++){
	out += this.layout[y][x]+" ";
      }
      out += "\n";
    }
    return out;
  };

  this.check_matches = function(){
    var closed_lines = new Array();
    for(var y = 0 ; y < BOARD_HEIGHT; y++){
      var matched = 0;
      for(var x = 0 ; x < BOARD_WIDTH; x++){
	if(this.layout[y][x] != 0){
	  matched += 1;
	}
      }
      if(matched == BOARD_WIDTH){
	closed_lines.push(y);
      }
    }
    if (closed_lines){
      SCORE += Math.pow(10,closed_lines.length)*closed_lines.length;
      this.update_score();
    }
    if(closed_lines.length > 0){
      for(var y = 0;y < closed_lines.length; y++){
	var newlayout = this.create_blank();
	var sline = closed_lines[y];
	for (var l = 0;l < BOARD_WIDTH;l++){
	  this.layout[sline].push("0");
	}
	for(var d = BOARD_HEIGHT;d > 0;d-=1){
	  if(d <= sline)
	    newlayout[d] = this.layout[d-1];
	  else
	    newlayout[d] = this.layout[d];
	}
	this.layout = newlayout;
      }
      //$(this.dom).remove();
      //this.render();
      this.layout = newlayout;
      this.full_update();
      return true;
    }
    return false;
  };

  this.render = function(){
    this.blocks = new Array();
    var inboard = this.layout;
    var board = document.createElement("div");
    $(board).addClass("board");
    var top = 0;
    for(var y = 0 ; y < BOARD_HEIGHT; y++){
      var row = document.createElement("div");
      $(row).addClass("row").css("top",top);
      var doma = new Array();
      var left = 0;
      for(var x = 0 ; x < BOARD_WIDTH; x++){
	var block = document.createElement("div");
	$(block).css("left",left).addClass("block");
	if(inboard && inboard.length > y && inboard[y][x] != "0"){
	  $(block).addClass("block-"+this.layout[y][x]);
	}else{
	  $(block).addClass("boardarea");
	}
	$(block).attr("id","section_"+x+"-"+y);
	left += BLOCK_WIDTH;
	doma.push(block);
	row.appendChild(block);
      }
      this.blocks.push(doma);
      top += BLOCK_HEIGHT;
      board.appendChild(row);
    }
    $(board).addClass("board").css("width",x*BLOCK_WIDTH).css("height",y*BLOCK_HEIGHT);
    document.getElementById('jtetris').appendChild(board);
    this.dom = board;
    return this;
  };

  this.full_update = function(){
    for(var y = 0 ; y < BOARD_HEIGHT; y++){
      for(var x = 0 ; x < BOARD_WIDTH; x++){
	if(this.blocks[y][x] == undefined)
	  continue;
	if(this.layout[y][x] == "0"){
	  this.blocks[y][x].setAttribute('class',"block boardarea");
	}else{
	  this.blocks[y][x].setAttribute('class',"block block-"+this.layout[y][x]);
	}
      }
    }
  };

  this.update = function(posy,posx){
    for(var y = posy; y < posy+6; y++){
      for(var x = 0 ; x < BOARD_WIDTH; x++){
	try{
	  if(this.layout[y][x] != "0"){
	    this.blocks[y][x].setAttribute('class',"block block-"+this.layout[y][x]);
	  }else{
	    this.blocks[y][x].setAttribute('class',"block boardarea");
	  }
	}catch(e){
	  continue;
	}
      }
    }
  };

  this.collision_check = function(pos_y,pos_x,piece){
    this.remove_piece(pos_y,pos_x,piece);
    height = piece.height;
    lpiece = piece;
    piece = piece.layout;

    if(pos_y+height >= BOARD_HEIGHT){
      this.add_piece(pos_y,pos_x,lpiece);
      return true;
    }
    for(y = 0; y < piece.length; y++){

      for(var x = 0; x < piece[y].length; x++){
	if(piece[y][x] == 0){
	  continue;
	}
	var check = this.layout[pos_y+y+1][pos_x+x];
	if(check != 0){
	  this.add_piece(pos_y,pos_x,lpiece);
	  return true;
	}
      }
    }
    this.add_piece(pos_y,pos_x,lpiece);
    return false;
  };

  this.right_collision_check = function(pos_y,pos_x,piece){
    this.remove_piece(pos_y,pos_x,piece);
    height = piece.height;
    lpiece = piece;
    piece = piece.layout;
    for(y = 0; y < piece.length; y++){
      for(var x = 0; x < piece[y].length; x++){
	if(piece[y][x] == 0){
	  continue;
	}
	var check = this.layout[pos_y+y][pos_x+x+1];
	if(check != 0){
	  this.add_piece(pos_y,pos_x,lpiece);
	  return true;
	}
      }
    }
    return false;
  };
  this.left_collision_check = function(pos_y,pos_x,piece){
    this.remove_piece(pos_y,pos_x,piece);
    height = piece.height;
    lpiece = piece;
    piece = piece.layout;
    for(y = 0; y < piece.length; y++){
      for(var x = 0; x < piece[y].length; x++){
	if(piece[y][x] == 0){
	  continue;
	}
	try{
	  var check = this.layout[pos_y+y][pos_x+x-1];
	}catch(e){
	  return false;
	}
	if(check != 0){
	  this.add_piece(pos_y,pos_x,lpiece);
	  return true;
	}
      }
    }
    return false;
  };

  this.add_piece = function(pos_y,pos_x,piece){
    piece = piece.layout;
    for(var y = 0; y < piece.length; y++){
      for(var x = 0; x < piece[y].length; x++){
	if(piece[y][x] != 0 || piece[y][x] != "0"){
	  if(this.layout[y+pos_y][x+pos_x] == 0){
	    this.layout[y+pos_y][x+pos_x] = piece[y][x];
	  }
	}
      }
    }
    return this;
  };
 this.update_score = function(){

    var score = document.getElementById('score')
      score.innerHTML = "<b>Score: </b>"+SCORE;
   if(SCORE > 1000){
     SPEED = 400
   }else if(SCORE > 5000){
     SPEED = 300
   }else if(SCORE > 10000){
     SPEED = 200
   }else if(SCORE > 100000){
     SPEED = 100
   }


  };
  this.remove_piece = function(pos_y,pos_x,piece){
    piece = piece.layout;
    for(var y = 0; y < piece.length; y++){
      for(var x = 0; x < piece[y].length; x++){
	if(piece[y][x] != 0 || piece[y][x] != "0"){
	  if(this.layout.length > y+pos_y)
	    this.layout[y+pos_y][x+pos_x] = "0";
	}
      }
    }
    return this;
  };
  this.layout = this.create_blank();
}

function Piece(piece_array){
  this.layout = piece_array;
  this.height = this.layout.length;

  this.find_width = function(){
    var width = 0;
    for(var y = 0; y < this.layout.length; y++){
      for(var x = 0;x < this.layout[y].length; x++){
	if(x != "0" || x != 0){
	  if(x > width){
	    width = x;
	  }
	}
      }
    }
    return width+2;
  };
  this.width = this.find_width();

  this.rotate_clockwise = function(){
    var piece = this.layout;
    var newp = new Array();
    for(var y = 0; y < piece.length; y++){
      var row = new Array();
      for(var x = 0; x < piece[y].length; x++){
	if(newp.length <= x)
	  newp.push(new Array());
	if(piece[y].length > this.width){
	  this.width = piece[y].length;
	}
	newp[x][y] = piece[y][x];
      }
    }
    for(var x = 0; x < newp.length; x++) newp[x].reverse();
    this.layout = newp;
    this.height = this.layout.length;
    this.width = this.find_width();
    return this;
  };
  this.render = function(){
    var piece = this.layout;
    var pdom = document.createElement("div");
    $(pdom).addClass("piece");
    var top = 0;
    for(var y = 0; y < piece.length; y++){
      var left = 0;
      var row = document.createElement("div");
      $(row).addClass("row");
      $(row).css("top",top);
      for(var x = 0; x < piece[y].length; x++){
	var block = document.createElement("div");
	$(block).html("&nbsp;");
	$(block).addClass("block-"+piece[y][x]);
	$(block).css("left",left).addClass("block");
	if(piece[y][x] == 0){
	  $(block).addClass("");
	}
	row.appendChild(block);
	left += BLOCK_WIDTH;
      }
      pdom.appendChild(row);
      top += BLOCK_HEIGHT;
    }
    this.dom = pdom;
    return this;
  };
  this.delete = function(){
    $(this.dom).remove();
    return this;
  };



}

var board;
$(document).ready(function(){

		    var piece = new Piece(PIECE_TYPES[rand(0,2)][0]);
		    var next_piece = new Piece(PIECE_TYPES[rand(0,PIECE_TYPES.length)][0]);
		    board = new Board;
		    board.render();
		    var nup = document.getElementById('jtetris').appendChild(document.createElement("div"));
		    nup.setAttribute("id","nextup");
		    nup.innerHTML = "<b>Next Piece</b>";
		    nup.appendChild(next_piece.render().dom);

                    var score = document.getElementById('jtetris').appendChild(document.createElement("div"));

                    score.setAttribute('id','score');
                    score.innerHTML = "<b>Score: </b>0";

		    var p_posy = 0;
		    var p_posx = 4;
		    var active_piece = piece;

		    function itervalfunc(){
		      if(board.collision_check(p_posy,p_posx,active_piece)){
			clearInterval(interval);
			if(board.check_matches()){
			  board.full_update();
			}
			active_piece = next_piece;
			next_piece = new Piece(PIECE_TYPES[rand(0,PIECE_TYPES.length)][0]);
			p_posy = 0;
			p_posx = 8;
			nup.innerHTML = "<b>Next Piece</b>";
			nup.appendChild(next_piece.render().dom);
			interval = setInterval(itervalfunc,SPEED);
			return 0;
		      }else{
			board.remove_piece(p_posy,p_posx,active_piece);
		      }
		      p_posy += 1;

		      board.add_piece(p_posy,p_posx,active_piece);
		      board.update(p_posy-1,p_posx-2);
		      //$('#testing').html(board.print_layout());
		      return true;
		    };
		    var interval = setInterval(itervalfunc,SPEED);
		    $(document).keypress(function(e){
					   if(board.collision_check(p_posy,p_posx,active_piece)){
					     clearInterval(interval);
					     active_piece = next_piece;
					     next_piece = new Piece(PIECE_TYPES[rand(0,PIECE_TYPES.length)][0]);
					     p_posy = 0;
					     p_posx = 8;
					     if(board.check_matches()){
					       board.full_update();
					     }
					     nup.innerHTML = "<b>Next Piece</b>";
					     nup.appendChild(next_piece.render().dom);
					     interval = setInterval(itervalfunc,500);
					     return 0;
					   }
					   board.remove_piece(p_posy,p_posx,active_piece);
					   //right arrrow
					   if(e.keyCode == 39){
					     if(!board.right_collision_check(p_posy,p_posx,active_piece))
					       p_posx	+= 1;
					   }
					   //left arrow
					   if(e.keyCode == 37){
					     if(!board.left_collision_check(p_posy,p_posx,active_piece))
					       p_posx	-= 1;
					   }
					   //down arrow
					   if(e.keyCode == 40){
					     p_posy	+= 1;
					   }
					   //up arrow
					   if(e.keyCode == 38){
					     active_piece.rotate_clockwise();
					   }
					   if(e.keyCode == 0){
					     board.full_update();
					   }
					   if(p_posx < 0)
					     p_posx = 0;
					   if(p_posx+active_piece.width > BOARD_WIDTH)
					     p_posx = (BOARD_WIDTH-active_piece.width)+1;
					   board = board.add_piece(p_posy,p_posx,active_piece);
					   board.update(p_posy-2,p_posx-2);
					   return true;
					 });
		  });