// ScreenLayout.js

// As seen on mediatemple account center. Thanks (mt)!

// The following code is courtesy of Joe Hewitt http://www.joehewitt.com
var _current_width = 0;

var _orientation = "profile";
    
function updateLayout() {
  if (window.innerWidth != _current_width) {  
    _current_width = window.innerWidth; var agent = navigator.userAgent.toLowerCase(); var isIphone = agent.indexOf('iphone') != -1 || agent.indexOf('ipod') != -1;
    if (isIphone) { var orient = _current_width == 320 ? "profile" : (_current_width > 1000 ? "profile" : "landscape"); document.body.setAttribute("orient", orient); _orientation = orient;
    } else { document.body.setAttribute("orient", "profile"); }
    setTimeout(function() { window.scrollTo(0, 1); }, 100);            
  }  
}

// end Joe Hewitt code. Thanks Joe!

// Helpers: cookie access.
function createCookie(name,value,days) { name = "tower" + name; var expires = ""; if (days) { var date = new Date(); date.setDate(date.getDate() + days); expires = "; expires=" + date.toGMTString(); } document.cookie = name + "=" + value + expires + "; path=/"; }
function readCookie(name) { name = "tower" + name; var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) { var v = c.substring(nameEQ.length, c.length); return v; } } return null; }
function eraseCookie(name) { createCookie(name, "" , -1); }
// Helpers: string builder.
function StringBuilder(value) { this.strings = [""]; if (value) this.append(value); }
StringBuilder.prototype.append = function(v) { this.strings.push(v); }
StringBuilder.prototype.appendList = function() { for (var i = 0; i < arguments.length; i++) this.strings.push(arguments[i]); }
StringBuilder.prototype.clear = function() { this.strings.length = 1; }
StringBuilder.prototype.toString = function() { return this.strings.join(""); }

// Main.js

var _after_help = null;

// Game management.
function show_help() {
  $("#help-container").css("display", "block").css("opacity", "0").animate({opacity: 0.9}, 400);
  
  createCookie("rulesShown", "1", 365);
}

function game_begin() {
  var canvas = $("#game-canvas").get(0);
  
  _canvas = canvas.getContext("2d");

  tower_initialize();
  tower_render();   

  // Force first initial update.
  _last_rendered = true;  

  $("#game-container").css("opacity", "0").css("display", "block");
  $("#game-container").animate({opacity: 1}, 400, function() {

    if (readCookie("rulesShown") != "1") {
      _after_help = function() { tower_begin_tick(); _after_help = null; }

      show_help();
    }
    else
      tower_begin_tick();
  });
}

function game_end(why) {
  $("#why").get(0).innerHTML = why;
  $("#points").get(0).innerHTML = "Score " + _target_score;

  $("#game-results").css("opacity", "0").css("display", "block");
  $("#game-results").animate({opacity: 0.9}, 400, function() {
  });
}

// Drawing canvas.
var _canvas;

// Current state of the tower.
var game_state = { start: 0, input: 1, rotate: 2, disappear: 3, scroll: 4, appear: 5 };
var _tower;
var _tower_sorter;
var _img_blocks;
var _state = game_state.start;
var _colors = 7;
var _captures = 0;
var _idle = 0;
var _sequence = 0;
var _turns = 0;
var _turn_cost = 20;
var _line_cost = 100;
var _time_add_1 = 17;
var _time_add_2 = 11;
var _time_add_3 = 7;

var _current_score = 0;
var _target_score = 0;

var _time = 0;
var _time_total = 45 * 20;

function tower_distance_sorter(a, b) {
  return a.d - b.d;
}

function tower_initialize() {
  _state = game_state.start;

  _colors = 7;
  _captures = 0;

  _current_score = 0;
  _target_score = 0;
  _turns = 0;

  _time = 30 * 20;

  $("#score").get(0).innerHTML = "";
  
  _tower = {};
  _tower_sorter = [];
  for (var j = 0; j < 5; ++j)
  {
    var l = [];

    for (var i = 0; i < 8; ++i)
      l.push({d: 0, i: i});

    _tower_sorter.push(l);
  }

  // Create rings.
  for (;;) {
    _tower.rings = [];

    var avail = [];  
    
    for (var i = 0; i < 5; ++i) {
      var ring = { target: 0, angle: 0, shift: 0, index: 2, blocks: [] };

      for (var j = 0; j < 8; ++j) {
        for (var k = 0; k < _colors; ++k)
          avail[k] = k;
        if (j != 0)
          avail[ring.blocks[j - 1].color] = -1;
        if (i != 0)
          avail[_tower.rings[i - 1].blocks[j].color] = -1;

        var c;
        for (;;) {
          c = Math.floor(Math.random() * _colors);
          if (avail[c] != -1)
            break;
        }
      
        ring.blocks.push({ color: c, mark: false, scale: 1, radius: (j % 2) == 0 ? 54 : 38, angle: j * 45, offset: 0 });
      }

      _tower.rings.push(ring);
    }

    if (check_more_matches())
      break;
  }

  tower_render();
}

var _tower_tick_timeout;
var _tower_ticking;

function tower_begin_tick() {
  if (!_tower_ticking) {
    _tower_ticking = true;

    tower_tick();
  }
}

function tower_end_tick() {
  _tower_ticking = false;

  if (_timer_tick_timeout) {
    clearTimeout(_tower_tick_timeout);
    _tower_tick_timeout = null;
  }
}

function tower_tick() {
  _timer_tick_timeout = null;

  var cont = tower_update();

  if (cont && _tower_ticking) 
    _timer_tick_timeout = setTimeout(tower_tick, 50);
}

function tower_check_matches(skip_marks) {
  var rings = _tower.rings;

  if (!skip_marks)
    for (var i = 0; i < rings.length; ++i)
      for (var j = 0; j < 8; ++j)
        rings[i].blocks[j].mark = false;    

  var m = [
    [ { v: 0, i: 0 }, { v: 0, i: 0 }, { v: 0, i: 0 } ],
    [ { v: 0, i: 0 }, { v: 0, i: 0 }, { v: 0, i: 0 } ],
    [ { v: 0, i: 0 }, { v: 0, i: 0 }, { v: 0, i: 0 } ]
  ];

  var empty_ring = { shift: 0, blocks: [] };
  for (var i = 0; i < 8; ++i)
    empty_ring.blocks.push({ color: -1 });

  for (var i = 0; i < rings.length; ++i) {    
    var ring_d_a = i == rings.length - 1 ? empty_ring : rings[i + 1];
    var ring_d_b = rings[i]
    var ring_d_c = i == 0 ? empty_ring : rings[i - 1];
    var ring_a = ring_d_a.blocks;
    var ring_b = ring_d_b.blocks;
    var ring_c = ring_d_c.blocks;

    for (var j = 0; j < 8; ++j) {
      var a_a = (j + ring_d_a.shift + 7) % 8; if (a_a < 0) a_a += 8;
      var a_b = (j + ring_d_a.shift + 0) % 8; if (a_b < 0) a_b += 8;
      var a_c = (j + ring_d_a.shift + 1) % 8; if (a_c < 0) a_c += 8;
      var b_a = (j + ring_d_b.shift + 7) % 8; if (b_a < 0) b_a += 8;
      var b_b = (j + ring_d_b.shift + 0) % 8; if (b_b < 0) b_b += 8;
      var b_c = (j + ring_d_b.shift + 1) % 8; if (b_c < 0) b_c += 8; 
      var c_a = (j + ring_d_c.shift + 7) % 8; if (c_a < 0) c_a += 8;
      var c_b = (j + ring_d_c.shift + 0) % 8; if (c_b < 0) c_b += 8;
      var c_c = (j + ring_d_c.shift + 1) % 8; if (c_c < 0) c_c += 8;

      if (skip_marks) {
        if (ring_b[b_b].color >= 0) {
          if (ring_b[b_b].color == ring_a[a_a].color && ring_a[a_a].color == ring_a[a_b].color) return true;
          if (ring_b[b_b].color == ring_a[a_b].color && ring_a[a_b].color == ring_a[a_c].color) return true;
          if (ring_b[b_b].color == ring_c[c_a].color && ring_c[c_a].color == ring_c[c_b].color) return true;
          if (ring_b[b_b].color == ring_c[c_b].color && ring_c[c_b].color == ring_c[c_c].color) return true;
          if (ring_b[b_b].color == ring_a[a_b].color && ring_a[a_b].color == ring_c[c_b].color) return true;
          if (ring_b[b_b].color == ring_b[b_a].color && ring_b[b_a].color == ring_b[b_c].color) return true;
        }
      } else {
        if (ring_b[b_b].color >= 0) {
          if (ring_b[b_b].color == ring_a[a_a].color && ring_a[a_a].color == ring_a[a_b].color) {
            ring_b[b_b].mark = true; ring_a[a_a].mark = true; ring_a[a_b].mark = true; }
          if (ring_b[b_b].color == ring_a[a_b].color && ring_a[a_b].color == ring_a[a_c].color) {
            ring_b[b_b].mark = true; ring_a[a_b].mark = true; ring_a[a_c].mark = true; }
          if (ring_b[b_b].color == ring_c[c_a].color && ring_c[c_a].color == ring_c[c_b].color) {
            ring_b[b_b].mark = true; ring_c[c_a].mark = true; ring_c[c_b].mark = true; }
          if (ring_b[b_b].color == ring_c[c_b].color && ring_c[c_b].color == ring_c[c_c].color) {
            ring_b[b_b].mark = true; ring_c[c_b].mark = true; ring_c[c_c].mark = true; }
                                                 
          if (ring_b[b_b].color == ring_a[a_b].color && ring_a[a_b].color == ring_c[c_b].color) {
            ring_b[b_b].mark = true; ring_a[a_b].mark = true; ring_c[c_b].mark = true; }
          if (ring_b[b_b].color == ring_b[b_a].color && ring_b[b_a].color == ring_b[b_c].color) {
            ring_b[b_b].mark = true; ring_b[b_a].mark = true; ring_b[b_c].mark = true; }
        }
      }
    }
  }

  var marked = false;

  if (!skip_marks) {
    for (var i = 0; i < rings.length; ++i) {
      for (var j = 0; j < 8; ++j) {
        if (rings[i].blocks[j].mark) {
          rings[i].blocks[j].scale = 1;
          marked = true;
        }        
      }
    }
  }

  return marked;
}

function tower_set_timebar(total, left) {
  $("#bar-fl").attr("width", left);
  $("#bar-fr").attr("width", total - left);
}

function tower_update() {
  var rings = _tower.rings;

  var need_render = false;

  if (_current_score != _target_score) {
    if (_current_score + 3000 < _target_score) {
      _current_score += 200;
    } else {
      _current_score += 30;
    }
    if (_current_score > _target_score)
      _current_score = _target_score;

    $("#score").get(0).innerHTML = _current_score + ""; 
  }

  if (_state == game_state.input) {
    need_render = false;

    _sequence = 0;

    if (--_time <= 0) {
      tower_end_tick();

      game_end("time's up!");

      return false;
    }

    tower_set_timebar(150, Math.round(_time / _time_total * 150));

    // Check for end of game due to no matches.
    if (++_idle == 5) {
      var count = 0;
      for (var i = 0; i < rings.length; ++i) {
        var ring = rings[i].blocks;
        for (var j = 0; j < 8; ++j) {  
          if (ring[j].color >= 0)
            ++count;
        }
      }      

      if (count == (rings.length * 8) && !check_more_matches()) {
        tower_end_tick();

        game_end("no matches left!");

        return false;
      }
    }
  }

  if (_state == game_state.rotate) {
    need_render = false;

    for (var i = 0; i < rings.length; ++i) {
      var ring = rings[i];

      var diff = 0;

      if (ring.target < ring.angle) {
        diff = -22.5; if (--ring.index < 0) ring.index += 4;

      } else if (ring.target > ring.angle) {
        diff = 22.5; if (++ring.index > 3) ring.index -= 4;
      }

      if (diff != 0) { 
        need_render = true;

        ring.angle += diff;
      }
    }

    if (!need_render) {
      need_render |= drop_blocks();

      if (tower_check_matches()) {
         if (_sequence == 0) {
           ++_turns;

           if (_turns < 3) 
             _time += _time_add_1 * 20;
           else if (_turns < 7) 
             _time += _time_add_2 * 20;
           else
             _time += _time_add_3 * 20;
        } else {
          _time += 2 * 20;
        }

        if (_time > _time_total)
          _time = _time_total;

        _state = game_state.disappear;

        // Adjust score.
        var blocks = 0;
        for (var i = 0; i < rings.length; ++i) {
          for (var j = 0; j < 8; ++j) {
            if (rings[i].blocks[j].mark)
              ++blocks;
          }
        }

        _target_score += blocks * 100 + _sequence * 50;

        ++_sequence;
      }
      else {
        _state = game_state.input;
        _idle = 0;
      }
    }
  }

  if (_state == game_state.start) {
    if (tower_check_matches())
      _state = game_state.disappear;
    else {
      _state = game_state.input;
      _idle = 0;
    }
  }

  if (_state == game_state.appear) {
    var switch_phase = false;
    
    need_render = true;

    var have_marked = false;
    
    for (var i = 0; i < rings.length; ++i) {
      for (var j = 0; j < 8; ++j) {
        if (rings[i].blocks[j].mark) {
          have_marked = true;
          rings[i].blocks[j].scale += 0.333333;
          if (rings[i].blocks[j].scale >= 1) {
            rings[i].blocks[j].scale = 1;
            rings[i].blocks[j].mark = false;
            switch_phase = true;
          }
        }        
      }
    }

    if (switch_phase || !have_marked) {
      _state = game_state.rotate;
    }
  }

  if (_state == game_state.scroll) {
    _state = game_state.appear;
  }

  if (_state == game_state.disappear) {
    var switch_phase = false;
    
    need_render = true;
    
    for (var i = 0; i < rings.length; ++i) {
      for (var j = 0; j < 8; ++j) {
        if (rings[i].blocks[j].mark) {
          rings[i].blocks[j].scale -= 0.333333;
          if (rings[i].blocks[j].scale <= 0.0001) {
            switch_phase = true;
          }
        }        
      }
    }

    if (switch_phase) {
      _state = game_state.scroll;

      drop_blocks();      
    }
  }
    
  if (need_render) {
    _canvas = $("#game-canvas").get(0).getContext("2d");
    
    tower_render();
  }

  return true;
}

function check_more_matches() {
  var rings = _tower.rings;

  var shifts = [ rings[1].shift, rings[2].shift, rings[3].shift ];

  var found = false;

  for (var i = 0; i < 8; i += 2) {
    for (var j = 0; j < 8; j += 2) {
      for (var k = 0; k < 8; k += 2) {
        rings[1].shift = shifts[0] + i;
        rings[2].shift = shifts[1] + j;
        rings[3].shift = shifts[2] + k;

        if (tower_check_matches(true)) {
          found = true;
          break;
        }
      }

      if (found)
        break;
    }

    if (found)
      break;
  }

  // Restore shifts.
  rings[1].shift = shifts[0];
  rings[2].shift = shifts[1];
  rings[3].shift = shifts[2];

  return found;
}

function drop_blocks() {
  var need_render = false;

  var rings = _tower.rings;

  for (var i = 0; i < rings.length; ++i)
    for (var j = 0; j < 8; ++j)
      rings[i].blocks[j].shift = 0;

  // Drop blocks.
  for (var j = 0; j < 8; ++j) {
    var offset = 0;
    
    // Calculate offsets.
    for (var i = 0; i < rings.length; ++i) {
      var k = (j + rings[i].shift) % 8; if (k < 0) k += 8;

      var block = rings[i].blocks[k];
                       
      block.offset = 0;
      if (block.mark || block.color < 0) {
        ++offset;
      } else {
        block.offset = offset;
      }
    }

    offset = 0;
    
    // Shift blocks.
    for (var i = 0; i < rings.length; ++i) {
      var k = (j + rings[i].shift) % 8; if (k < 0) k += 8;

      var block = rings[i].blocks[k];

      if (!block.mark && block.color >= 0)
        offset++;

      if (block.offset > 0) {
        var m = (j + rings[i - block.offset].shift) % 8; if (m < 0) m += 8;

        rings[i - block.offset].blocks[m] = block;
        block.angle = m * 45;

        block.offset = 0;

        need_render = true;

        // Clear out old block position.
        rings[i].blocks[k] = { color: -1, scale: 0, angle: 0, radius: (j % 2) == 0 ? 54 : 38 };
      }              
    }    

    // Clear out marks.
    for (var i = offset; i < rings.length; ++i) {
      var k = (j + rings[i].shift) % 8; if (k < 0) k += 8;

      rings[i].blocks[k] = { color: -1, scale: 0, angle: 0, radius: (j % 2) == 0 ? 54 : 38 };
    }
  }

  return need_render;
}

function tower_buy_one_line() {
  var rings = _tower.rings;

  // Generate one line of new blocks.

  for (var j = 0; j < rings[0].blocks.length; ++j) {    
    for (var i = 0; i < rings.length; ++i) {
      var ring = rings[i];

      var k = (j + ring.shift) % 8; if (k < 0) k += 8;
      if (ring.blocks[k].color >= 0)
        continue;

      var avail = [];

      for (var l = 0; l < _colors; ++l)
        avail[l] = l;
       
      k = (j + ring.shift + 7) % 8; if (k < 0) k += 8;
      avail[ring.blocks[k].color] = -1;
      k = (j + ring.shift + 1) % 8; if (k < 0) k += 8;
      avail[ring.blocks[k].color] = -1;
      if (i != 0) {
        k = (j + rings[i - 1].shift) % 8; if (k < 0) k += 8;
        avail[rings[i - 1].blocks[k].color] = -1;
      } 

      var c;
      for (;;) {
        c = Math.floor(Math.random() * _colors);
        if (avail[c] != -1 || Math.random() > 0.55)
          break;
      }

      k = (j + rings[i].shift) % 8; if (k < 0) k += 8;

      var block = 
        { color: c, mark: true, scale: 0, radius: (k % 2) == 0 ? 54 : 38, angle: k * 45, offset: 0 };

      ring.blocks[k] = block;
      
      break;
    }
  }
}

function tower_render() {
  _canvas.clearRect(0, 0, 300, 300);

  if (!_img_blocks) {
    _img_blocks = new Image();
    _img_blocks.src = "imgs/sprites.png";
  }

  var rings = _tower.rings;
           
  var center_x = 80;

  for (var i = 0; i < rings.length; ++i) {
    var ring = rings[i];   
    var l = _tower_sorter[i];

    for (var j = 0; j < 8; ++j) {
      var b = ring.blocks[j];
      var r = ((ring.angle + b.angle) * Math.PI) / 180;
      l[j].d = Math.cos(r) * b.radius;
      l[j].i = j;
    }

    l.sort(tower_distance_sorter);
  }

  var center_y = 180;  
  for (var i = 0; i < rings.length; ++i) {
      var ring = rings[i];
    
  for (var j = 0; j < rings[0].blocks.length; ++j) {

      var ring_angle = ring.angle;
      if (ring.index == 1)
        ring_angle += 11.25;
      if (ring.index == 3)
        ring_angle -= 11.25;

      var block = ring.blocks[_tower_sorter[i][j].i];
            
      if (block.color >= 0)
        block_draw(center_x, center_y, ring_angle, ring, block);
    }    
    center_y -= 27;
  }  
}

function block_draw(x, y, ring_angle, ring, block) {  
  var r = ((ring_angle + block.angle) * Math.PI) / 180;

  var cy = y + Math.cos(r) * block.radius * 0.7;
  var cx = x + Math.sin(r) * block.radius;

  var sprite_index = ring.index;

  var offset_x = sprite_index * 48;
  var offset_y = block.color * 54;

  if (block.scale == 1) {
    try {
      _canvas.drawImage(_img_blocks, 
        offset_x, offset_y, 48, 54, Math.round(cx) - 24, Math.round(cy) - 27, 48, 54);
    } catch (err) {
    }
  } else {
    var sx = Math.round(48 * block.scale);
    var sy = Math.round(54 * block.scale);

    if (offset_x >= 0 && offset_y >= 0 && sx > 0 && sy > 0) {
      try {
        _canvas.drawImage(_img_blocks, 
          offset_x, offset_y, 48, 54, Math.round(cx - 24 + (48 - sx) / 2), Math.round(cy - 27 + (54 - sy) / 2), sx, sy);
      } catch (err) {
      }
    }
  }
}


// Initialization.

// Image preloading.

var _preload_init = [ "imgs/underclouds.png", "imgs/background.jpg", "imgs/logo.png" ];
var _preload_continue = [ "imgs/sprites.png", "imgs/arrows.png", "imgs/timebar.png" ];
var _preload_continue_count = _preload_continue.length;

function fixup_logo() {
  $("#brand").css("background", "transparent url(imgs/underclouds.png) no-repeat center");

  $("#logo-inner").css("background", "transparent url(imgs/background.jpg) no-repeat top center");
  $("#game-inner").css("background", "transparent url(imgs/background.jpg) no-repeat top center");
  $("#logo-img").attr("src", "imgs/logo.png");
}

function fixup_preload() {
  $("#btn-l-1").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#btn-l-2").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#btn-l-3").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#btn-l-4").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#btn-l-5").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#btn-r-1").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");
  $("#btn-r-2").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");
  $("#btn-r-3").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");
  $("#btn-r-4").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");
  $("#btn-r-5").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");

  $("#btn-left").css("background", "transparent url(imgs/arrows.png) no-repeat -48px 0px");
  $("#btn-right").css("background", "transparent url(imgs/arrows.png) no-repeat -75px 0px");

  $("#help-left").css("background", "transparent url(imgs/arrows.png) no-repeat 0px 0px");
  $("#help-right").css("background", "transparent url(imgs/arrows.png) no-repeat -24px 0px");

  $("#help-rotate-left").css("background", "transparent url(imgs/arrows.png) no-repeat -48px 0px");
  $("#help-rotate-right").css("background", "transparent url(imgs/arrows.png) no-repeat -75px 0px");

  $(".arrow").css("opacity", "0.5");

  $("#bar-l").css("background", "transparent url(imgs/timebar.png) no-repeat 0px 0px");
  $("#bar-fl").css("background", "transparent url(imgs/timebar.png) repeat-x 0px -26px");
  $("#bar-fr").css("background", "transparent url(imgs/timebar.png) repeat-x 0px -39px");
  $("#bar-r").css("background", "transparent url(imgs/timebar.png) no-repeat 0px -13px");
}

$(function() {
  // Begin images preloading.
  $(document.createElement('img')).bind('load', function() {
    if(_preload_init[0]) {
      this.src = _preload_init.shift();
    } else {               
      $("#preloading").css("display", "none");

      fixup_logo();

      $("#brand").animate({opacity: 1}, 1500, function() {
        setTimeout(function() {          
          $("#brand").animate({opacity: 0}, 1500, function() {
            $("#logo").animate({opacity: 1}, 1000, function() {
              $("#brand").css("display", "none");

              window.scrollTo(0, 1);
            });
          });
        }, 2000);
      });      
      
      $(document.createElement('img')).bind('load', function() {
        if(_preload_continue[0]) {
          this.src = _preload_continue.shift(); 
        } else {
          fixup_preload();          

          $("#logo-loading").css("display", "none");
          $("#logo-loaded").css("display", "inline");

          setTimeout(function() {
           updateLayout();   
   
           window.scrollTo(0, 1);

           setInterval(updateLayout, 100); 
          }, 300);
        }
      }).trigger('load');      
    }
  }).trigger('load');

  $("#btn-left").click(function() {
    if (_state != game_state.input)
      return false;

    var rings = _tower.rings;
    for (var i = 0; i < rings.length; ++i) {
      rings[i].target -= 90; rings[i].shift += 2;
    }

    _state = game_state.rotate;

    return false;
  });

  $("#btn-right").click(function() {
    if (_state != game_state.input)
      return false;

    var rings = _tower.rings;
    for (var i = 0; i < rings.length; ++i) {
      rings[i].target += 90; rings[i].shift -= 2;
    }

    _state = game_state.rotate;

    return false;
  });  

  $("#btn-l-1").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[4].target -= 90; _tower.rings[4].shift += 2; return false; });
  $("#btn-l-2").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[3].target -= 90; _tower.rings[3].shift += 2; return false; });
  $("#btn-l-3").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[2].target -= 90; _tower.rings[2].shift += 2; return false; });
  $("#btn-l-4").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[1].target -= 90; _tower.rings[1].shift += 2; return false; });
  $("#btn-l-5").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[0].target -= 90; _tower.rings[0].shift += 2; return false; });

  $("#btn-r-1").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[4].target += 90; _tower.rings[4].shift -= 2; return false; });
  $("#btn-r-2").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[3].target += 90; _tower.rings[3].shift -= 2; return false; });
  $("#btn-r-3").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[2].target += 90; _tower.rings[2].shift -= 2; return false; });
  $("#btn-r-4").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[1].target += 90; _tower.rings[1].shift -= 2; return false; });
  $("#btn-r-5").click(function() { if (_state != game_state.input) return false; _target_score -= _turn_cost; if (_target_score < 0) _target_score = 0; _state = game_state.rotate; _tower.rings[0].target += 90; _tower.rings[0].shift -= 2; return false; });

  $("#btn-start").click(function() {
    window.scrollTo(0, 1);

    $("#logo").animate({opacity: 0}, 400, function() {
      $("#logo").css("display", "none"); 
    });

    game_begin();

    return false;
  });

  $("#btn-help").click(function() {
    show_help();

    return false;
  });

  $("#help-continue").click(function() {
    $("#help-container").animate({opacity: 0}, 400, function() {
      $("#help-container").css("display", "none");

      if (_after_help) {
        _after_help();
      }
    });

    return false;
  });

  $("#btn-end").click(function() {
    tower_end_tick();

    game_end("");

    return false
  });

  $("#btn-buy-gems").click(function() { 
    tower_buy_one_line();

    _target_score -= _line_cost;
    if (_target_score < 0)
      _target_score = 0;

    _state = game_state.appear;

    return false;
  });

  $("#results-continue").click(function() {
    // Save scores.
    var name = $("#grats-name").val();

    createCookie("name", name, 365);
    if (_target_score > 0 && name != "nickname") {
      $.post("score.php", 
        { name: name,
          version: 2,
          level: 0,
          total: _target_score }, function(xml) {});
    }

    $("#game-container").animate({opacity: 0}, 200, function() {
      $("#game-container").css("display", "none");
    });

    $("#game-results").animate({opacity: 0}, 400, function() {
      $("#game-results").css("display", "none");

      $("#logo").css("display", "block").css("opacity", "0").animate({opacity: 1}, 400);
    });
   
    return false;
  });

  $("#btn-scores").click(function() {
    $("#scores-loading").css("display", "block");
    $("#scores-table").css("display", "none");
    $("#scores-container").css("display", "block").css("opacity", "0").animate({opacity: 1}, 400, function() {

      $.post("score.php", {}, function(xml) {
        var sb = new StringBuilder();

        sb.appendList("<div class='scores-header'>All Time Best</div>");

        $("a > v", xml).each(function() {
          var n = $("<div/>").text($(this).attr("n")).html();

          sb.appendList("<div class='score-line'><div class='name'>", 
            n, "</div><div><span class='score'>",
            $(this).attr("t"), "</span></div></div>");
        });

        $("#scores-all").get(0).innerHTML = sb.toString();

        sb = new StringBuilder();

        sb.appendList("<div class='scores-header'>Today's Best</div>");

        $("q > v", xml).each(function() {
          var n = $("<div/>").text($(this).attr("n")).html();

          sb.appendList("<div class='score-line'><div class='name'>", 
            n, "</div><div><span class='score'>",
            $(this).attr("t"), "</span></div></div>");
        });

        $("#scores-today").get(0).innerHTML = sb.toString();

        $("#scores-loading").css("display", "none");
        $("#scores-table").css("display", "block");
      });
    });

    return false;
  });

  $("#btn-scores-continue").click(function() {
    $("#scores-container").animate({opacity: 0}, 400, function() {
      $("#scores-container").css("display", "none");
    });

    return false;
  });                  

  var agent = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase() : "";
  var is_iphone = agent && (agent.indexOf('iphone') != -1 || agent.indexOf('ipod') != -1);

  if (!is_iphone) {
    $("#pc-padding").css("display", "block");
  }

  var name = readCookie("name");

  if (name && name.length > 0)
    $("#grats-name").val(name);  
  else
    $("#grats-name").val("nickname");  

  document.body.setAttribute("orient", "profile");
});
