/****
**
**  Blocks (blocks_online.js)
**
**  2007 Guido Stammel
**
****/


var knownBoards = new Array(
  '#:#13....#:###.2..#:#...#..#:#...#.1#:#34..#:#432..3#:#',
  '#:#.6.5....#:#.3.6....#:#.2.2.4.1#:#.5.3.1.4#:#',
  '#:#4.###.3.#:#24.#.213#:##21.21#:###414#:#',
  '#:#..53#:#..64#:##.71#:##.2#:##.#:##2.#:#76..#:#45..#:#13..#:#',
  '#:##.....#:#.....1#:#....24#:#...375#:#..2756#:#.1346#:#',
  '#:###.7.#:#..3#.#:#.###.#:#.#...#:#...7.#:#.###3#:#',
  '#:#..1..#:#..6..#:#.###.#:#..1..#:#..6.1#:#6#:#',
  '#:#5...2#:##o.o#:#.o.o.#:#.o.o.#:#.o.o.#:#.o.o.#:#.o.o.#:#.o.o.#:#2o.o5#:#',
  '#:###16.#:#..2#.#:#.###.#:#.#.2.#:#..162#:#.#:#',
  '#:##4.#:###1#:##.o#:##.1#:##.o#:#..1.#:#..4.#:##.#..#:##....#:###.4.#:#',
  '#:#.64.63.#:#.16.14.#:#.43.31.#:####.#:#.......#:#.......#:#.......#:#',
  '#:##..3.#:##.##.#:#......#:#.3434.#:##4343#:##3434#:#',
  '#:#31.....31#:####.#.#:#....#....#:#.#######.#:#.........#:##.#####.#:##..2.2..#:#',
  '#:##.85..21.#:##.###.##.#:##4##..##3#:#.7##.###4.#:#.2.6..1.5.#:#.3###.##6.#:#.8......7.#:#',
  '#:##2.#:###2#:##.o#:##.o#:##.o#:#..o#:#..o.#:#.#o.#:#.##.#:#....#:###.2.#:#',
  '#:#......#:#6.....#:#o75.#:#534....#:#o12....#:#128....#:####....#:##..84.6#:##.54367#:#',
  '#:#...........#:#........2..#:#..1...213..#:#..2...546..#:#..1...354..#:####...####.#:####...####.#:####....6...#:####...#:#',
  '#:#35.........#:###....#21..#:##.....###..#:##........5.#:##......172.#:##...6..###.#:######.6#...#:#####..34...#:#####.648...#:#####.387..#:#',
  '#:#.............#:#.............#:#67.........53#:###.........#:##...........#:##6.........2#:###4........#:###o1..4..53#:#####7.o.2#:######1#.#:#',
  '#:##.........#:#....6.1....#:#...##.##...#:#...........#:#...........#:#.........4.#:#26.......34#:##26.1.1.34#:#',
  '#:#5.........7.#:###6......8#:####25...1#:#####3...4#:######..#:######....#:####......#:####12..7.#:######348.#:#########6#:#',
  '#:#2....756..14.#:##.#######.#:##.........#:##........3#:##.......#:######......#:#####.......#:#####..215....#:#####213467...#:#',
  '#:#3.........6.#:###8......5#:####43...7#:#####1...2#:######..#:######.....#:####.........#:####74..6....#:######125....#:#########8..#:#',
  '#:#35.......#:#####21...#:#...###...#:#......5..#:#....172..#:#.6..###..#:#.#.6#.#..#:###.34....#:#..648...#:##.387..#:#',
  '..........#:......2...#:..........#:...2......#:..........#:#',
  '...2......#:..###..2..#:......###.#:..........#:..........#:...2......#',
  '#:##.2###..#:##23...54#:###4...4#:####3.5#:#',
  '##5..5.#:##3..4.2#:###5.5.#:##.43#..#:##32##3.#:#',
  '..........#:.234..254.#:.325..345.#:.###..###.#:..........#:#........#',
  '.23.42.52.#:.##.##.##.#:..........#:#..#..#..#:#35####24#:#',
  '#:##2o2..3#:###3o.o#:#:#:#',
  '##.52...#:##.#o43.#:##..###.#:##...32.#:##.54##.#:##.####.#',
  '#:###.5..#:##2423.3#:##354534#:###4325#:#',
  '#:##2....34#:##32..3#:##4#23#:####32.#:#',
  '#:##.34.53.#:##.##.##.#:##243..5.#:####5..2.#:#',
  '###54.o...#:#####.###5#:###3.....#:#####.##3#:###2....#:#####4#2#',
  '##52..42#:###3..3#:####..#:##34..25#:##4o..32#:#',
  '#:##52..45#:##34..23#:####.2#:####43#:#',
  '##45..#:####..43#:##23..#:####..43#:##52..#:####3.25#',
  '34..42.242#:535.##.435#:##24..42#:####..#:#:#',
  '#:#..2345..#:###5432#:#..2345..#:#:#',
  '#:##.243o.#:##.52o4.#:##.3o32.#:##.o345.#:#',
  '#:#5######4#:#34..2435#:##2#.###4#:#:#',
  '#:###..34#:##...235#:##5..423#:###..53#:#',
  '..24..32..#:..##..##..#:.34.23.43.#:.##.##.##.#:..52..35..#:..##..##..#',
  'o345..234o#:####..#:....5.....#:...4o.....#:..3##.....#:.2###.....#',
  '#:532.##.534#:###....#:o35.##.245#:#:#',
  '#:##..2...#:##.345..#:##543245#:##234323#:#',
  '..34..2532#:.2##5.3#:.#..2.432.#:..43#.###3#:.2523..245#:.####..#',
  '#234..34.#:####..#:.#43..34#.#:.###..###.#:.#23..42#.#:.###..###.#',
  '#:#..14#:#..35#:##.62#:##.7#:##.#:##7.#:#63..#:#51..#:#24..#:#',
  '#:#8765.41#:#####.#:#8..#.32#:###.#.#:###....8#:###.#74#:###.#823#:###.#615#:#',
  '#:#12......#:###1.....#:####.....#:###.3..4.#:#...##.5.#:#...##.6.#:#...#..#.#:#....4.#.#:#.2735.#.#:#.3276.#:#',
  '#:#.85...#:#.731..#:#.62#..#:#.###..#:#.#....#:#.#8...#:#.#65..#:#..842.#:#.####851#:#.542#732#:#',
  '#:##.1.#:#1.21#:##.32#:##.43#:##.54#:##.65#:##.76#:##.87#:##.18#:#',
  '#:#.45##16.#:#268##728#:#713..435#:####..#:#........#:#........#:#........#:#78.##5.6#:#236##784#:#451##231#:#',
  '#:#72.#....#:#134#...7#:#865...6#:#####.3#:#....2#:#...1#:#..4#:#.5#:#8#:#',
  '#:#......#:#...56.#:#.27##.#:#.##...#:#.#.52.#:#.76##.#:#.####.#:#..##..#:#',
  '#:#...##...#:#.78##78.#:#.46##25.#:#.######.#:#...##...#:#35.##.36#:#12....14#:#',
  '#:#.3....#:#.1..4.#:#.#.81.#:#...7#.#:#..53..#:#7.2#..#:#6.1...#:#4.#...#:#2..568#:#',
  '#:#..........#:#...4..3...#:#...1..2...#:#...#..#...#:##........#:###.4321.#:#',
  '#:#..2..3..#:#..1..1..#:#..#..#..#:#........#:#.3..3213#:#',
  '#:#121.3.31#:#24241242#:#31414313#:#423##421#:#131..342#:#',
  '#:##...##...#:#1...##...3#:##...##...#:#3..3......#:##324##3..#:#.431##24.1#:##312##324#:#',
  '#:#...41.#:#.32##.#:#.##...#:#...43.#:#..1##.#:#.###..#:#2.##..#:#',
  '#:#..#.3..#:#..1.23.#:#..#.12.#:#..#.41.#:#..#.34.#:#..#.23.#:#..#.124#:#',
  '#:#..1...2..4#:#.###.###.#:#.4.3....2.#:###.###.#:#.2....1..3#:#.###.###.#:#..........#:#',
  '#:####.####.#:#.2#.#..3.#:#.##.#.24.#:#.#...431.#:#..3.#2##.#:#4.#3#31#.#:#32#4####.#:#',
  '#:#.....3....#:#...4.1....#:#2..2.#...3#:##..#.....#:##.4....1.#:##.231..34#:#',
  '#:###.#3.#.3#:##1.4#.3.2#:#.#.#..#.#.#:#..........#:#.2.3##4.1.#:#',
  '#:#..........#:#....4.....#:#...213....#:#...4##2.2.#:#.2.#..#.1.#:#.#......#3#:##..34.34.#:#',
  '#:#4.......1.#:#1...4.2.#.#:##.12#.#1.3#:#..3#.4.2.#:#..#..3.#..#:#.....#....#:#..........#:#',
  '#:#......1...#:#..........#:#..4..2....#:#..#4441...#:#..#.......#:#..........#:#..#.242...#:#',
  '#:####..#:#42#..#2#:##13..23#:####..#:###1.3#:###2#4#:#',
  '#:#...##..33.#:#..#33#..3.#:#..3113..3.#:#.333333.3.#:#..3333..3.#:#..#33#..3.#:#3.#..#.33.#:#',
  '#:#..1..111..#:#.11.1..#..#:#1#1.1#....#:#..1.1111..#:##.1.1##.1.#:#..1.1..#1.#:#..1..111..#:#',
  '#:#...4.4.4.4#:#..33..3332#:#..1.2#313.#:#.########.#:#.22222222.#:#.1##11##1.#:#..##..##..#:#',
  '#:#43#.#34#:#12...12#:####.#:#2.#.#12#:#43...34#:#',
  '#:#14#..3#:#.3..2#:###.3#:#..1#:#.4#:#2#:#',
  '#:#44444..#:#..44...#:#.......#:#..1.1..#:#..#1#..#:#.#####.#:#',
  '#:##........#:#..######..#:#.#34##43#.#:#..12##21..#:#..######..#:#..........#:###...4..#:#',
  '#:#1432434242#:#3241321313#:#143####432#:#312....213#:#2413123434#:##12141212#:##31413431#:#',
  '#:#1..3#:#3..1#:##..#:#1..3#:##..#:##12#:##21#:#',
  '#:#.1.2.2.3.1#:##3#3#3#4#3#:#.4.1.4.1.2#:##2#4#2#4#4#:#.4.1.1.3.3#:#.3.2.3.1.2#:#',
  '#:#2.#2#:##.#1#.2.#:#1.#3#.#.#:##.#4#.1.#:#..#2#.#.#:#3.....4.#:#',
  '#:##........#:#..........#:#13..12..32#:###..##..#:#..........#:#..........#:##........#:#',
  '#:#......#:#.2..2.#:#',
  '#:#......#:#.3..3.#:#.2..2.#:#',
  '#:#1...#:###.1#:###1#:#',
  '#:#1.2..1.2#:##.####.#:#........#:#.######.#:#........#:#',
  '#:#1.....#:#3.....#:#1...13#:###.#:#',
  '#:#......#:#35....#:#714...#:####.43o1#:####3o157#:#',
  '#:##..3...#:#..121...#:#1.###..3#:#2....o.#:#'
);
var gameString = '';
var cols = 10, rows = 6;
var activeItem = false;
var isBlocked = false;


//
//
//
function onClickImg( img ) {

  if( isBlocked ) return;

  var cell = img.parentNode.parentNode;
  var temp = new String( cell.id ).split( '_' );
  var col = new Number( temp[ 1 ] );
  var row = new Number( temp[ 2 ] );

  var cell_type = getCellType( col, row );
  if( isMovable( cell_type ) ) {
    activeItem = new Array( );
    activeItem.x = col;
    activeItem.y = row;
    blinkActiveItem( );
    return;
  }

  if( col < activeItem.x ) {
    isBlocked = true;
    moveLeft( activeItem.x, activeItem.y, activeItem.x - col );
  }

  if( col > activeItem.x ) {
    isBlocked = true;
    moveRight( activeItem.x, activeItem.y, col - activeItem.x );
  }

  activeItem = false;

}


//
//
//
function unblinkItem( cell_id ) {

  var cell = document.getElementById( cell_id );
  var img = cell.getElementsByTagName( 'img' )[ 0 ];

  img.style.visibility = 'visible';

}


//
//
//
function blinkActiveItem( ) {

  if( typeof activeItem == 'boolean' ) return;

  var cell_id = 'cell_' + activeItem.x + '_' + activeItem.y;
  var cell = document.getElementById( cell_id );
  var img = cell.getElementsByTagName( 'img' )[ 0 ];

  img.style.visibility = 'hidden';

  setTimeout( 'unblinkItem( "' + cell_id + '" )', 200 );
  setTimeout( 'blinkActiveItem( )', 400 );

}


//
//
//
function getCellType( col, row ) {

  var cell_id = 'cell_' + col + '_' + row;
  var cell = document.getElementById( cell_id );

  var cell_type = cell.getAttribute( 'type' );

  return cell_type;

}


//
//
//
function isMovable( cell_type ) {

  switch( cell_type ) {
    case 'gem1':
    case 'gem2':
    case 'gem3':
    case 'gem4':
    case 'gem5':
    case 'gem6':
    case 'gem7':
    case 'gem8':
    case 'stone':
      return true;

    default:
      return false;

  }

}


//
//
//
function isCollectable( cell_type ) {

  switch( cell_type ) {
    case 'gem1':
    case 'gem2':
    case 'gem3':
    case 'gem4':
    case 'gem5':
    case 'gem6':
    case 'gem7':
    case 'gem8':
      return true;

    default:
      return false;

  }

}


//
//
//
function moveLeft( col, row, count ) {

  var src_type = getCellType( col, row );
  if( !isMovable( src_type ) ) {
    isBlocked = false;
    return false;
  }

  var dst_type = getCellType( col - 1, row );
  if( dst_type != 'empty' ) {
    isBlocked = false;
    return false;
  }

  setCell( col, row, 'empty' );
  setCell( col - 1, row, src_type );

  if( doPhysics( false, true ) == false ) {
    if( count > 1 ) {
      isBlocked = true;
      setTimeout( 'moveLeft( ' + (col - 1) + ', ' + row + ', ' + (count - 1) + ' )', 200 );
      return;
    }
  }

}


//
//
//
function moveRight( col, row, count ) {

  var src_type = getCellType( col, row );
  if( !isMovable( src_type ) ) {
    isBlocked = false;
    return false;
  }

  var dst_type = getCellType( col + 1, row );
  if( dst_type != 'empty' ) {
    isBlocked = false;
    return false;
  }

  setCell( col, row, 'empty' );
  setCell( col + 1, row, src_type );

  if( doPhysics( false, true ) == false ) {
    if( count > 1 ) {
      isBlocked = true;
      setTimeout( 'moveRight( ' + (col + 1) + ', ' + row + ', ' + (count - 1) + ' )', 200 );
    }
  }

}


//
//
//
function setRecursiveMarker( field, sfield, col, row, marker ) {

  count = 1;
  sfield[ col ][ row ] = marker;

  if( field[ col ][ row ] == field[ col + 1 ][ row ] ) {
    if( sfield[ col + 1 ][ row ] == 0 ) {
      count += setRecursiveMarker( field, sfield, col + 1, row, marker );
    }
  }

  if( field[ col ][ row ] == field[ col - 1 ][ row ] ) {
    if( sfield[ col - 1 ][ row ] == 0 ) {
      count += setRecursiveMarker( field, sfield, col - 1, row, marker );
    }
  }

  if( field[ col ][ row ] == field[ col ][ row + 1 ] ) {
    if( sfield[ col ][ row + 1 ] == 0 ) {
      count += setRecursiveMarker( field, sfield, col, row + 1, marker );
    }
  }

  if( field[ col ][ row ] == field[ col ][ row - 1 ] ) {
    if( sfield[ col ][ row - 1 ] == 0 ) {
      count += setRecursiveMarker( field, sfield, col, row - 1, marker );
    }
  }

  return count;

}


//
//
//
function deleteTiles( field, sfield, marker ) {

  for( var i = 0; i < cols; i++ ) {
    for( var j = 0; j < rows; j++ ) {
      if( sfield[ i ][ j ] == marker ) {
        field[ i ][ j ] = 0;
        setCell( i, j, 'empty' );
      }
    }
  }

}


//
//
//
function doPhysics( bReal, bWait ) {

  var bMoved = false;

  if( typeof bWait == 'undefined' ) bWait = false;

  var field = new Array( );
  var sfield = new Array( );
  for( var i = -1; i <= cols; i++ ) {
    field[ i ] = new Array( );
    sfield[ i ] = new Array( );
    for( var j = -1; j <= rows; j++ ) {
      field[ i ][ j ] = 'wall';
      sfield[ i ][ j ] = 0;
    }
  }

  for( var i = 0; i < cols; i++ ) {
    for( var j = rows - 1; j >= 0; j-- ) {
      field[ i ][ j ] = getCellType( i, j );
      if( isMovable( field[ i ][ j ] ) && (field[ i ][ j + 1 ] == 'empty') ) {
        if( bReal ) {
          setCell( i, j + 1, field[ i ][ j ] );
          setCell( i, j, 'empty' );
        }
        bMoved = true;
      }
    }
  }

  if( bMoved ) {
    setTimeout( 'doPhysics( true )', 200 );
    return true;
  }

  tile_count = 0;
  for( var i = 0; i < cols; i++ ) {
    for( var j = 0; j < rows; j++ ) {
      if( !isCollectable( field[ i ][ j ] ) ) continue;
      count = setRecursiveMarker( field, sfield, i, j, ++tile_count );
      if( count > 1 ) {
        if( bWait == false ) {
          deleteTiles( field, sfield, tile_count );
        }
        bMoved = true;
      }
    }
  }

  if( bMoved ) {
    setTimeout( 'doPhysics( true )', 200 );
    return true;
  }

  if( isFinished( ) ) {
    setTimeout( 'nextBoard( )', 500 );
  }

  isBlocked = false;
  return false;

}


//
//
//
function setCell( col, row, value ) {

  var cell_id = 'cell_' + col + '_' + row;
  var cell = document.getElementById( cell_id );
  cell.setAttribute( 'type', value );
  var cell_img = cell.getElementsByTagName( 'img' )[ 0 ];
  cell_img.src = 'gfx/' + value + '.jpg';

}


//
//
//
function resizeBoard( cols, rows ) {

  var gameTable = document.getElementById( 'gameTable' );
  var gameTableBody = false;

  var gameTRs = gameTable.getElementsByTagName( 'tr' );
  while( gameTRs.length ) {
    gameTableBody = gameTRs[ 0 ].parentNode;
    gameTRs[ 0 ].parentNode.removeChild( gameTRs[ 0 ] );
  }

  for( var j = 0; j < rows; j++ ) {
    var newTR = document.createElement( 'tr' );
    for( var i = 0; i < cols; i++ ) {
      var newIMG = document.createElement( 'img' );
      newIMG.setAttribute( 'style', 'width: 3em; height: 3em;' );
      newIMG.setAttribute( 'src', 'gfx/wall.jpg' );
      newIMG.onmousedown = function( ) {
        onClickImg( this );
      }

      var newDIV = document.createElement( 'div' );
      newDIV.setAttribute( 'style', 'width: 3em; height: 3em;' );
      newDIV.appendChild( newIMG );

      var newTD = document.createElement( 'td' );
      newTD.setAttribute( 'id', 'cell_' + i + '_' + j );
      newTD.appendChild( newDIV );
      newTR.appendChild( newTD );
    }
    gameTableBody.appendChild( newTR );
  }

}


//
//
//
function isFinished( ) {

  for( var i = 0; i < cols; i++ ) {
    for( var j = 0; j < rows; j++ ) {
      if( isCollectable( getCellType( i, j ) ) ) return false;
    }
  }

  return true;

}


//
//
//
function nextBoard( ) {

  var board = Math.floor( Math.random( ) * knownBoards.length );
  gameString = knownBoards[ board ];
  resetBoard( );

}


//
//
//
function resetBoard( ) {

  var tempLines = new String( gameString ).split( ':' );

  cols = 0;
  rows = tempLines.length;
  for( var i = 0; i < rows; i++ ) {
    tempLines[ i ] = new String( tempLines[ i ] );
    if( tempLines[ i ].length > cols ) {
      cols = tempLines[ i ].length;
    }
  }

  resizeBoard( cols, rows );
  for( var i = 0; i < cols; i++ ) {
    for( var j = 0; j < rows; j++ ) {
      switch( tempLines[ j ].charAt( i ) ) {
        case '.':
          cell_type = 'empty';
          break;

        case '1':
          cell_type = 'gem1';
          break;

        case '2':
          cell_type = 'gem2';
          break;

        case '3':
          cell_type = 'gem3';
          break;

        case '4':
          cell_type = 'gem4';
          break;

        case '5':
          cell_type = 'gem5';
          break;

        case '6':
          cell_type = 'gem6';
          break;

        case '7':
          cell_type = 'gem7';
          break;

        case '8':
          cell_type = 'gem8';
          break;

        case 'o':
          cell_type = 'stone';
          break;

        default:
          cell_type = 'wall';
          break;

      }
      setCell( i, j, cell_type );
    }
  }

  activeItem = false;
  isBlocked = true;
  doPhysics( false, true );

}


/****
**
**  End of File (blocks_online.js)
**
****/
