var config =
{
  pieceDir: '../image/pieces/',
  pieceExt: '.png',
  bitmapWidth: 50,
  bitmapHeight: 50,
  fieldColorWhite: 'white',
  fieldColorBlack: '#888888',
  fieldColorGray: '#FACEAA',
  whiteMoveImage: '../image/pieces/whitemove.png',
  blackMoveImage: '../image/pieces/blackmove.png',
  availableMove: '../image/pieces/lime-border.png',
  availableTaking: '../image/pieces/red-border.png'
};

function RefreshBoard(div, boardTd)
{
  div.boardTds = new Array(0x88);

  var table = document.createElement('TABLE');
  table.cellPadding = '0px';
  table.cellSpacing = '0px';

  var tbody = document.createElement('TBODY');

  for (rank=7; rank>=0; --rank)
  {
    var tr = document.createElement('TR');
    tr.style.height = config.bitmapHeight + 'px';
    for (file=0; file<8; ++file)
    {
      var td = document.createElement('TD');
      td.style.width = config.bitmapWidth + 'px';
      td.style.height = config.bitmapHeight + 'px';

      td.style.backgroundColor = (file ^ rank) & 1 ? config.fieldColorWhite : config.fieldColorBlack;

      var what = div.position.board[file + 16*rank];
      if (what != '.')
      {
        var filename = GetColor(what) + what.toLowerCase();
        td.style.backgroundImage = 'url(' + config.pieceDir + filename + config.pieceExt + ')';
      }

      if (div.position.phase == 4)
      {                             
        if (div.position.activeSide == GetColor(what)) 
          td.style.cursor = 'pointer';
      } 

      td.isBoard = true;
      td.divId = div.id;
      td.file = file;
      td.rank = rank;
      div.boardTds[file + 16*rank] = td;
      tr.appendChild(td);
    }
    tbody.appendChild(tr);
  }

  table.appendChild(tbody);
  table.style.border = 'solid 1px black';

  boardTd.appendChild(table);
}
 
function RefreshReserve(div, reserveTd)
{
  var table = document.createElement('TABLE');
  table.cellPadding = '0px';
  table.cellSpacing = '0px';

  var tbody = document.createElement('TBODY');

  for (rank=7; rank>=0; --rank)
  {
    var tr = document.createElement('TR');
    tr.style.height = config.bitmapHeight + 'px';
    for (file=0; file<8; ++file)
    {
      var td = document.createElement('TD');
      td.style.width = config.bitmapWidth + 'px';
      td.style.height = config.bitmapHeight + 'px';
      td.style.border = 'solid 1px #888888';

      td.divId = div.id;
      td.rank = rank;
      td.file = file;

      td.style.backgroundColor = config.fieldColorGray;

      var what = div.position.reserv[file + 16*rank];
      if (what != '.')
      {
        var filename = GetColor(what) + what.toLowerCase();
        td.style.backgroundImage = 'url(' + config.pieceDir + filename + config.pieceExt + ')';
      }

      if (div.position.phase == 1 && what == '$')
      {                             
        if (div.position.activeSide == 'w' && rank == 3) 
        {
          td.style.cursor = 'pointer';
        }
        if (div.position.activeSide == 'b' && rank == 4) 
          td.style.cursor = 'pointer';
      } 

      if (div.position.phase == 2)
      {                             
        if (div.position.activeSide == 'w' && what == 'K') 
          td.style.cursor = 'pointer';
        if (div.position.activeSide == 'b' && what == 'k') 
          td.style.cursor = 'pointer';
      } 

      if (div.position.phase == 3 || div.position.phase == 4)
      {                             
        if (div.position.activeSide == GetColor(what)) 
          td.style.cursor = 'pointer';
      } 

      td.isBoard = false;
      tr.appendChild(td);
    }
    tbody.appendChild(tr);
  }

  table.appendChild(tbody);
  table.style.border = 'solid 1px black';

  reserveTd.appendChild(table);

  if (!div.isMouseDownHandler)  
  {
    AddHandler(div, 'mousedown', TdMouseDown);      
    div.isMouseDownHandler = true;
  }  
}

function Refresh(div)
{
  div.isMainDiv = true;

  var boardTd;
  var reserveTd;

  var table = document.createElement('TABLE');
  var tbody = document.createElement('TBODY');
  var tr = document.createElement('TR');
  for (i=0; i<3; ++i)
  {
    var td = document.createElement('TD');
    var width = i != 1 ? 8*config.bitmapWidth : 48;
    td.style.width = width + 'px';
    td.style.height = 8*config.bitmapWidth + 'px';
    if (i==0) boardTd = td;
    if (i==1)
    {
      var img = document.createElement('IMG');
      if (div.position.activeSide == WHITE)
      {
        img.src = config.whiteMoveImage;
        td.style.verticalAlign = 'bottom';
      }
      else  {
        img.src = config.blackMoveImage;
        td.style.verticalAlign = 'top';
      }
      td.appendChild(img);
    }
    if (i==2) reserveTd = td;
    tr.appendChild(td);
  }   

  RefreshBoard(div, boardTd);
  RefreshReserve(div, reserveTd);

  tbody.appendChild(tr);
  table.appendChild(tbody);
  div.appendChild(table);

  var p;
  var span = document.createElement('SPAN');

  p = document.createElement('P');
  p.innerHTML = GetDescription(div.position);
  span.appendChild(p);

  p = document.createElement('P');
  p.innerHTML = '<b>FEN</b> = <span class="fen">' + BuildFen(div.position) + '</span>';
  span.appendChild(p);
  
  div.appendChild(span);
}

function GetDescription(position)
{
  switch(position.phase)
  {
    case 1:
      return '<b>Phase I:</b> You must put obstacles. <b>' + position.phaseArg + '</b> moves later.';
    case 2:
      return '<b>Phase II:</b> You must put kings.'; 
    case 3:
      return '<b>Phase III:</b> You must put pieces for battle. <b>' + position.phaseArg + '</b> moves later.';
    case 4:
      return '<b>Phase IV:</b> You can move now!';
  }
  return '<b>PHASE ??? :(</b> Contact to developer (Mustitz)';
}

function SetDiagram(divId, fen, passId)
{
  var div = $(divId);
  var pass = $(passId);
  var position = BuildPosition(fen);

  if (typeof(position) == 'string')
  {
    alert('Error!!! ' + position);
    return;
  }

  ClearElement(div);  
  div.position = position;
  Refresh(div);
  div.history = [fen];

  div.pass = pass;
  pass.div = div;  
  
  if (!pass.isClickHandler)  
  {
    AddHandler(pass, 'click', PassClick);
    pass.isClickHandler = true;
  }  
}


function SetFen(div, pass)
{
  var fen = prompt('Input position FEN:', '');
  if (typeof(fen) == 'string' && fen != '') SetDiagram(div, fen, pass);
}

function PassClick(e)
{
  var div = GetTarget(e).div;

  var isOk = DoPass(div.position);

  ClearElement(div);  
  Refresh(div);

  if (isOk)
    div.history.push(BuildFen(div.position));  
  else
    alert('PASS is not suported now.');
}

function TdMouseDown(e)
{
  var td = FindParent(GetTarget(e), 'TD'); 
  if (td == null) return;
  if (typeof(td.file) == 'undefined') return;
  
  PreventDefault(e);
  
  var div = $(td.divId);
  var position = div.position;

  if (position.result != '*') return;
  
  var piece = td.isBoard ? position.board[td.file + 16*td.rank] : position.reserv[td.file + 16*td.rank];
  if (piece == '.') return;

  switch(position.phase)
  {
    case 1:
      if (td.isBoard) return;
      if (piece != '$') return;
      if (position.activeSide == 'w' && td.rank != 3) return;
      if (position.activeSide == 'b' && td.rank != 4) return;
      break;
    case 2:
      if (td.isBoard) return;
      if (position.activeSide == 'w' && piece != 'K') return;
      if (position.activeSide == 'b' && piece != 'k') return;
      break;
    case 3:
      if (td.isBoard) return;
    case 4:
      if (position.activeSide != GetColor(piece)) return;
      break;
    default:
      return;
  }

  var availableMoves = CalculateAvailable(position, td.isBoard ? 'board' : 'reserve', td.file, td.rank);
  if (availableMoves == null) return;

  for (f=0; f<8; ++f)
    for (r=0; r<8; ++r)
  {
    if (!availableMoves[f+16*r]) continue;
    var img = document.createElement('img');
    img.src = position.board[f+16*r] == '.' ? config.availableMove : config.availableTaking;
    div.boardTds[f+16*r].appendChild(img);
  }

  var imgDiv = document.createElement('div');
  var offset = CalculateAbsoluteOffset(td);
  imgDiv.style.position = 'absolute';
  imgDiv.style.left = offset.left + 'px';
  imgDiv.style.top = offset.top + 'px';
  imgDiv.style.width = config.bitmapWidth + 'px';
  imgDiv.style.height = config.bitmapHeight + 'px';
  imgDiv.style.backgroundImage = td.style.backgroundImage;
  imgDiv.zIndex = 10;
  
  td.style.backgroundImage = '';
  div.appendChild(imgDiv);

  div.dragTd = td;
  div.dragDiv = imgDiv;
  div.dragLastX = e.clientX;
  div.dragLastY = e.clientY;
  div.drag = td.isBoard ? 'board' : 'reserve';

  AddHandler(div, 'mousemove', TdMouseMove);
  AddHandler(div, 'mouseup', TdMouseUp);
}

function TdMouseMove(e)
{
  PreventDefault(e);

  var node = GetTarget(e);
  for(;;)
  {
    node = FindParent(node, 'DIV');
    if (typeof(node) == 'indefined') 
    {
      RemoveHandler(div, 'mousemove', TdMouseMove);
      RemoveHandler(div, 'mouseup', TdMouseUp);
      
      div.dragTd = null;
      div.dragDiv = null;
      div.dragLastX = null;
      div.dragLastY = null;
      div.drag = null;

      return;
    }
    if (typeof(node.dragTd) != 'undefined') break;
    node = ParentNode(node);
  }  
  
  var div = node;
  Move(div.dragDiv, e.clientX - div.dragLastX, e.clientY - div.dragLastY);
  div.dragLastX = e.clientX;
  div.dragLastY = e.clientY;
}

function TdMouseUp(e)
{
  PreventDefault(e);

  var node = GetTarget(e);
  for(;;)
  {
    node = FindParent(node, 'DIV');
    if (typeof(node) == 'undefined') return;
    if (typeof(node.dragTd) != 'undefined') break;
    node = ParentNode(node);
  }  

  var div = node;
  Move(div.dragDiv, e.clientX - div.dragLastX, e.clientY - div.dragLastY);
  div.dragLastX = e.clientX;
  div.dragLastY = e.clientY;
  
  var divOffset = CalculateAbsoluteOffset(div);
  var dragDivOffset = CalculateAbsoluteOffset(div.dragDiv);
  var divMouseLeft = dragDivOffset.left - divOffset.left;
  var divMouseTop = dragDivOffset.top - divOffset.top;
  var x = Math.round(divMouseLeft / config.bitmapWidth);
  var y = Math.round(divMouseTop / config.bitmapHeight);
  var file = x;
  var rank = 7 - y;

  var isOk = DoMove(div.position, div.drag, div.dragTd.file, div.dragTd.rank, file, rank);

  ClearElement(div);  
  Refresh(div);

  if (isOk)
    div.history.push(BuildFen(div.position));  
  
  RemoveHandler(div, 'mousemove', TdMouseMove);
  RemoveHandler(div, 'mouseup', TdMouseUp);
  
  div.dragTd = null;
  div.dragDiv = null;
  div.dragLastX = null;
  div.dragLastY = null;
  div.drag = null;

  if (div.position.result != '*')
    alert('Game over with result ' + div.position.result);
}