// ScreenLayout.js

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

// The following code is courtesy of Joe Hewitt http://www.joehewitt.com
var _orientation = "profile";
    
function updateLayout(orientation)
{
  if (typeof(orientation) == "undefined")
    orientation = _orientation;

  var agent = navigator.userAgent.toLowerCase();
  var isIphone = agent.indexOf('iphone') != -1 || agent.indexOf('ipod') != -1;    

  if (orientation == "force") {
    if (isIphone) {
      var o = window.orientation;
      switch(o) {
        case 0:
          orientation = "profile";
          break;
        case 90:
          orientation = "landscape";
          break;
        case -90:  
          orientation = "landscape";
          break;
      }
    }
    else
      orientation = _orientation;
    _orientation = "";  
  }

  if (orientation != _orientation)
  {  
    if (isIphone) {
      ++_flips;

      var orient = orientation;
      document.body.setAttribute("orient", orient);

      if (orient == "profile") {
        _gravity = v_(0.0, 11.0);

        $(".content").css("width", "320px");
        $("#field-outer").css("width", "320px").css("height", "302px").css("padding-top", "54px");
        $("#field-profile").css("display", "block");
        $("#field-landscape").css("display", "none");
        $("#kick-profile").css("display", "block");
        $("#kick-landscape").css("display", "none");
        $("#prev-profile").css("display", "block");
        $("#prev-landscape").css("display", "none");
        $("#reset-profile").css("display", "block");
        $("#reset-landscape").css("display", "none");
        $("#menu-profile").css("display", "block");
        $("#menu-landscape").css("display", "none");
        $("#donate-profile").css("display", "block");
        $("#donate-landscape").css("display", "none");
        $("#next-profile").css("display", "block");
        $("#next-landscape").css("display", "none");
      }
      else {
        _gravity = v_(11.0, 0.0);

        $(".content").css("width", "480px");
        $("#field-outer").css("width", "480px").css("height", "258px").css("padding-top", "10px");
        $("#field-profile").css("display", "none");
        $("#field-landscape").css("display", "block");
        $("#kick-profile").css("display", "none");
        $("#kick-landscape").css("display", "block");
        $("#prev-profile").css("display", "none");
        $("#prev-landscape").css("display", "block");
        $("#reset-profile").css("display", "none");
        $("#reset-landscape").css("display", "block");
        $("#menu-profile").css("display", "none");
        $("#menu-landscape").css("display", "block");
        $("#donate-profile").css("display", "none");
        $("#donate-landscape").css("display", "block");
        $("#next-profile").css("display", "none");
        $("#next-landscape").css("display", "block");

      }

      _orientation = orient;
    } else {
      document.body.setAttribute("orient", "profile");
    }

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

// end Joe Hewitt code. Thanks Joe!

// Utils.js 

if (document.all && !document.getElementById) { document.getElementById = function(id) { return document.all[id]; } }

function createCookie(name,value,days) {
  name = "gravity" + 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 = "gravity" + 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);
}

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("");
}

// Physics.js

function v_(x, y) { return {x:x, y:y}; }
function v_c(a) { return {x:a.x, y:a.y}; }
function v_add(a, b) { return {x:a.x + b.x, y:a.y + b.y}; }
function v_sub(a, b) { return {x:a.x - b.x, y:a.y - b.y}; }
function v_mul(a, b) { return {x:a.x * b, y:a.y * b}; }
function v_madd(a, b, c) { return {x:a.x + b.x * c, y: a.y + b.y * c}; }
function v_madd_ref(a, b, c) { a.x += b.x * c; a.y += b.y * c; }
function v_dot(a, b) { return a.x * b.x + a.y * b.y; }
function v_len(a) { return Math.sqrt(v_dot(a, a)); }
function v_nor(a) { var inv_len = 1.0 / Math.sqrt(a.x * a.x + a.y * a.y); return {x:a.x * inv_len, y:a.y * inv_len}; }
function v_nor_2(a, b) { var inv_len = 1.0 / Math.sqrt(a * a + b * b); return {x:a * inv_len, y:b * inv_len}; }
function p_(x, y, z) { return {x:x, y:y, z:z}; }
function p_dot(p, v) { return p.x * v.x + p.y * v.y + p.z; }
function v_crs(a) { return {x:-a.y, y:a.x}; }

function ph_plane_sphere(plane, begin, delta, radius) {
  var n_dot_d = plane.x * delta.x + plane.y * delta.y;
  var dist_b = plane.x * begin.x + plane.y * begin.y + plane.z;

  var ta, tb;

  if (n_dot_d == 0.0) {
    if (Math.abs(dist_b) > radius)
      return null;

    ta = 0;
    tb = 1;
  } else {
    ta = (radius - dist_b) / n_dot_d;
    tb = (-radius - dist_b) / n_dot_d;

    if (ta > tb) { var tc = ta; ta = tb; tb = tc; }      
    if (ta > 1 || tb < 0) return null;
    if (ta < 0) ta = 0;
    if (tb > 1) tb = 1;
  }  

  return v_(ta, tb);
}

function ph_1d_intersect(line_begin, line_end, center, radius_squared) {  
  if (center > line_begin && center < line_end)
    return center;

  var d_begin = (center - line_begin) * (center - line_begin);
  if (d_begin < radius_squared)
    return line_begin;

  var d_end = (center - line_end) * (center - line_end);
  if (d_end < radius_squared)
    return d_end;

  return null
}		

function root(a, b, c, bound) {
  var determinant = b * b - 4.0 * a * c;
  if (determinant < 0.0)
    return null;

  var q = -0.5 * (b + (b < 0.0 ? -1.0 : 1.0) * Math.sqrt(determinant));

  var x1 = q / a;
  var x2 = c / q;

  if (x2 < x1) { var x3 = x1; x1 = x2; x2 = x3; }

  if (x1 >= 0.0 && x1 <= bound)
    return x1;
  if (x2 >= 0.0 && x2 <= bound)
    return x2;

  return null;
}

function ph_1d_swept_intersect(line_begin, line_end, begin, delta, a, b, c) {
  var upper_bound = 1.0;
  var collision = false;
  var point = null;

  var b_to_v = line_begin - begin;
  var a1 = a - delta * delta;
  var b1 = b + 2.0 * delta * b_to_v;
  var c1 = c - b_to_v * b_to_v;

  var t = root(a1, b1, c1, upper_bound);
  if (t) {
    collision = true;
    upper_bound = t;
    point = line_begin;
  }

  b_to_v = line_end - begin;
  a1 = a - delta * delta;
  b1 = b + 2.0 * delta * b_to_v;
  c1 = c - b_to_v * b_to_v;

  var t = root(a1, b1, c1, upper_bound);
  if (t) {
    collision = true;
    upper_bound = t;
    point = line_end;
  }

  return collision ? v_(upper_bound, point) : null;
}

function ph_line_sphere(line_plane, line_begin, line_end, begin, delta, radius) {
  var t = ph_plane_sphere(line_plane, begin, delta, radius);
  if (t == null)
    return null;

  var n_dot_d = v_dot(line_plane, delta);
  var dist_b = p_dot(line_plane, begin);
  var a = -n_dot_d * n_dot_d;
  var b = -2 * n_dot_d * dist_b;
  var c = radius * radius - dist_b * dist_b;

  var u = v_crs(line_plane);
  var begin_plane = v_dot(u, begin);
  var delta_plane = v_dot(u, delta);

  var p = ph_1d_intersect(line_begin, line_end, begin_plane + delta_plane * t.x, a * t.x * t.x + b * t.x + c);
  if (p) {
    return v_(t.x, 
      v_(u.x * p - line_plane.x * line_plane.z, u.y * p - line_plane.y * line_plane.z));
  }

  var p = ph_1d_swept_intersect(line_begin, line_end, begin_plane, delta_plane, a, b, c);
  if (p) {
    return v_(p.x, 
      v_(u.x * p.y - line_plane.x * line_plane.z, u.y * p.y - line_plane.y * line_plane.z));
  }

  return null;
}

function ph_ray_sphere(ray_start, ray_direction, length, center, radius) {
  var offset_x = center.x - ray_start.x;
  var offset_y = center.y - ray_start.y;
  var ray_distance = ray_direction.x * offset_x + ray_direction.y * offset_y;
  if (ray_distance <= 0 || (ray_distance - length) > radius)
    return null;

  var offset_squared = offset_x * offset_x + offset_y * offset_y;
  var radius_squared = radius * radius;
  if (offset_squared <= radius_squared)
    return v_(0.0, ray_start);
  var d = radius_squared - (offset_squared - ray_distance * ray_distance);
  if (d < 0)
    return null;
  var fraction = ray_distance - Math.sqrt(d);
  if (fraction > length)
    return null;

  return v_(fraction / length, v_madd(ray_start, ray_direction, fraction));
}

function ph_sphere_sphere(static_center, static_radius, begin, delta, radius)	{
  var length = v_len(delta);

  if (length == 0.0)
    return null;

  var t = ph_ray_sphere(begin, v_mul(delta, 1.0 / length), length, static_center, static_radius + radius);
  if (t) {
    var intersection_point = v_madd(begin, delta, t.x);
    var d = v_sub(static_center, intersection_point);

    return v_(t.x, v_madd(intersection_point, d, radius));
  } else 
    return null;
}

var _walls = [];

function add_wall(x1, y1, x2, y2) {
  var a = v_(x1, y1);
  var b = v_(x2, y2);
  var n = v_crs(v_nor(v_sub(b, a)));
  var d = -v_dot(n, a);

  var u = v_crs(n);

  var ua = v_dot(u, a);
  var ub = v_dot(u, b);

  if (ua > ub) { var uc = ua; ua = ub; ub = uc; }

  _walls.push({p:p_(n.x, n.y, d), b:ua, e: ub});
}

var _triggers = [];

function add_trigger(x, y, r, n) {  
  _triggers.push({x: x, y: y, r: r, n: n});
}

function remove_trigger(n) {
  for (var i = 0; i < _triggers.length; ++i)
    if (_triggers[i].n == n) {
      if (_triggers.length > 1) 
        _triggers[i] = _triggers[_triggers.length - 1];
      _triggers.pop();

      break;
    }
}

var _attractors = [];

function add_attractor(x, y, m) {
  _attractors.push({x: x, y: y, m: m});
}

var _ball;

function set_ball(center, radius, mass) {
  _ball = {c:center, r:radius, v:v_(0, 0), f:v_(0, 0), m:1.0 / mass};
}

var _time;

var _gravity = v_(0.0, 11.0);

function reset_simulation() {
  _time = 0.0;
  _walls = [];
  _triggers = [];
  _attractors = [];
}

var _on_trigger = null;

function set_on_trigger(fn) {
  _on_trigger = fn;
}

function step_simulation(step) {
  target = _time + step;
  
  var was_collision = false;

  while (_time < target) {
    var seconds = target - _time;

    var collision_time = null;
    var collision_point = null;
    var collision_normal = null;

    var delta = v_mul(_ball.v, seconds);

    for (var i = 0; i < _walls.length; ++i) {
      var w = _walls[i];
      var t = ph_line_sphere(w.p, w.b, w.e, _ball.c, delta, _ball.r);
      if (t) {
        var valid = false;

        var intersection_time = t.x * seconds;
        if (intersection_time == 0.0) {
          var normal_direction = v_sub(_ball.c, t.y);
          if (v_dot(_ball.v, normal_direction) < 0.0)
            valid = true;
        } else
          valid = true;

        if (valid) {
          if (!collision_time || intersection_time < collision_time) {
            collision_time = intersection_time;
            collision_point = t.y;            
            collision_normal = v_nor_2(
              _ball.c.x + _ball.v.x * collision_time - t.y.x,
              _ball.c.y + _ball.v.y * collision_time - t.y.y);
          }
        }
      }
    }

    for (var i = 0; i < _triggers.length; ++i) {
      var d = _triggers[i];
      var t = ph_sphere_sphere(d, d.r, _ball.c, delta, _ball.r);
      if (t) {
        var intersection_time = t.x * seconds;

        if ((collision_time && intersection_time <= collision_time) || !collision_time) {
          if (_on_trigger) {
            _on_trigger(d.n);
          }

          break;
        }
      }
    }

    if (collision_time)
      was_collision = true;

    // Integrate up to the moment of collision.
    var step_time = collision_time ? collision_time : seconds;

    var old = v_(_ball.c.x, _ball.c.y);

    v_madd_ref(_ball.c, _ball.v, step_time);
    v_madd_ref(_ball.v, _ball.f, step_time * _ball.m);

    if (collision_time) {
      if (_game_mode == 0) 
        v_madd_ref(_ball.v, collision_normal, -(1.0 + 0.7) * v_dot(_ball.v, collision_normal));
      else
        v_madd_ref(_ball.v, collision_normal, -(1.0 + 0.85) * v_dot(_ball.v, collision_normal));
      _ball.f = v_(0.0, 0.0);
    }
	_time += step_time;
  }

  if (!was_collision)
  {
    _ball.f = v_c(_gravity);

    var velocity = _ball.v;
    var vel = v_dot(velocity, velocity);
    if (vel > 0.0) {
      velocity = v_nor(velocity);
      v_madd_ref(_ball.f, velocity, -1);
    }

    if (_attractors) {
      for (var i = 0; i < _attractors.length; ++i) {
        var a = _attractors[i];

        var x = a.x - _ball.c.x;
        var y = a.y - _ball.c.y;

        var l = Math.sqrt(x * x + y * y);

        if (l < 2)
          continue;
        
        var nx = x / l;
        var ny = y / l;

        var f = a.m / (l * l);

        if (f > 100)
          f = 100;

        _ball.f.x += nx * f;
        _ball.f.y += ny * f;
      }
    }

    var fl = Math.sqrt(_ball.f.x * _ball.f.x + _ball.f.y * _ball.f.y);
    if (fl > 300) {
      _ball.f.x = _ball.f.x / fl * 300;
      _ball.f.y = _ball.f.y / fl * 300;
    }
  }
}

// Main.js

function make_img(v) {
  return $.browser.msie ? ("imgs/1/" + v) : ("imgs/" + v);
}

var img_complete = make_img("complete.png");
var img_tap = make_img("tap.png")
var img_l = make_img("l.png");
var img_ball = make_img("ball.png");
var img_best = make_img("best.png");
var img_go = make_img("go.png");
var img_start = make_img("start.png");
var img_advanced = make_img("advanced.png");
var img_help = make_img("help.png");
var img_exit = make_img("othergames.png");
var img_done = make_img("done.png");
var img_dev = make_img("dev.png");

var preload_init = [ "imgs/underclouds.png", "imgs/bg.jpg" ];
var preload_continue = [ "imgs/ball.png", "imgs/dot.png", 
  img_start, img_advanced, img_help, img_exit, img_l, img_tap, img_complete, img_best, img_go, img_done, img_dev,
  "imgs/instructions.png", "imgs/kick-h.png", "imgs/kick-v.png", "imgs/flip.png", "imgs/m-h.png", "imgs/m-v.png"
];

var _ajax_seed = 0;

function fixup_preload() {  
  $("#btn-start > img").attr("src", img_start);
  $("#btn-advanced > img").attr("src", img_advanced);
  $("#btn-help > img").attr("src", img_help);
  $("#btn-exit > img").attr("src", img_exit);
  $("#kick-profile > img").attr("src", "imgs/kick-h.png");
  $("#kick-landscape > img").attr("src", "imgs/kick-v.png");
  $("#flip-profile > img").attr("src", "imgs/flip.png");

  $("#prev-profile > img").css("background", "url(imgs/m-h.png) no-repeat 0px -30px");
  $("#prev-landscape > img").css("background", "url(imgs/m-v.png) no-repeat -30px 0px");
  $("#reset-profile > img").css("background", "url(imgs/m-h.png) no-repeat 0px -15px");
  $("#reset-landscape > img").css("background", "url(imgs/m-v.png) no-repeat -45px 0px");
  $("#menu-profile > img").css("background", "url(imgs/m-h.png) no-repeat 0px 0px");
  $("#menu-landscape > img").css("background", "url(imgs/m-v.png) no-repeat -60px 0px");
  $("#next-profile > img").css("background", "url(imgs/m-h.png) no-repeat 0px -45px");
  $("#next-landscape > img").css("background", "url(imgs/m-v.png) no-repeat -15px 0px");

  $("#btn-donate-profile").css("background", "url(imgs/m-h.png) no-repeat 0px -60px");
  $("#btn-donate-landscape").css("background", "url(imgs/m-v.png) no-repeat 0px 0px");
  
  $("#help-outer").css("background-image", "url(imgs/instructions.png)");
  $("#btn-tap-img").attr("src", img_tap);
  $("#btn-go").attr("src", img_go);
}

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

function begin_level_continue() {
  initialize_simulator(_current_level[_game_mode]);

  if (readCookie("rulesShown") != "1") {
    $("#help-container").css("opacity", "0").css("display", "block").animate(
      {opacity: 1}, 400);

    createCookie("rulesShown", "1", 365);
  }
}

var _gravity_kick_ready = true;

function gravity_kick() {
  if (_simulator_timer && _gravity_kick_ready)
  {
    ++_kicks;

    _ball.f = v_add(_ball.f, v_mul(_gravity, -40));

    _gravity_kick_ready = false;

    $(".btn-kick").css("opacity", "0.3");
    
    setTimeout(function() {
      _gravity_kick_ready = true;
      $(".btn-kick").css("opacity", "1");
    }, 1400);
  }
}

var _current_level = [ 0, 0 ];
var _max_level = [ 0, 0 ];
var _game_mode = 0;
var _triggers_left;

function on_simulator_trigger(n) {
  if ($.browser.msie) {
    document.getElementById("dot" + n + "p").outerHTML = "";
    document.getElementById("dot" + n + "l").outerHTML = "";
  } else {
    $("#dot" + n + "p").css("display", "none");
    $("#dot" + n + "l").css("display", "none");
  }

  remove_trigger(n);

  --_triggers_left;

  if (_triggers_left == 0) {
    stop_simulator();

    if (_current_level[_game_mode] < _max_level[_game_mode])
      ++_current_level[_game_mode];
    else {
      ++_max_level[_game_mode];
      ++_current_level[_game_mode];
    }

    if (_game_mode == 0) {
      createCookie("max_level", "" + _max_level[_game_mode], 365);
      createCookie("current_level", "" + _current_level[_game_mode], 365);
    } else {
      createCookie("max_level_adv", "" + _max_level[_game_mode], 365);
      createCookie("current_level_adv", "" + _current_level[_game_mode], 365);
    }

    var best = false;

    if (_hi_flips + _hi_kicks > _flips + _kicks) {
      $("#grats").attr("src", img_best);
      best = true;
    } else {
      $("#grats").attr("src", img_complete);
    }    

    $("#grats-score").get(0).innerHTML = _flips + " flips / " + _kicks + " kicks";

    if (!best) {
      $("#grats-record").css("display", "none");

      $("#grats-container").css("display", "block").css("opacity", "1");
      $("#grats").css("width", "10px").css("height", "5px").css("opacity", "0").animate(
        {opacity: 1, width: 239, height: 120}, 250, function() {
          $("#grats").animate({width: 171, height: 86}, 400);
        });
    
      setTimeout(function() {
        $("#grats-container").animate({opacity: 0}, 400, function() {
          $("#grats-container").css("display", "none");

          initialize_simulator(_current_level[_game_mode]);
        });
      }, 5000);
    } else {
      $("#grats-record").css("display", "block");      

      $("#grats-container").css("display", "block").css("opacity", "1");
      $("#grats").css("width", "10px").css("height", "5px").css("opacity", "0").animate(
        {opacity: 1, width: 279, height: 49}, 250, function() {
          $("#grats").animate({width: 200, height: 35}, 400, function() { 
          });
        });
    }
  }
}

var _flips = 0;
var _kicks = 0;

var _hi_flips = 0;
var _hi_kicks = 0;

var _levels = [0, 0];

function initialize_simulator(level) {
  _current_level[_game_mode] = level;
  _flips = 0;
  _kicks = 0;
  _hi_flips = 0;
  _hi_kicks = 0;

  reset_simulation();

  if (_current_level[_game_mode] >= _levels[_game_mode] || !levels[_game_mode][level])
  {
    $("#btn-tap").css("display", "block");
    $("#btn-tap-img").attr("src", img_done);
    $("#tap-score").get(0).innerHTML = "tap prev to play<br/>favorite levels again";

    return;
  }

  add_wall(0,   0,   0,   240);
  add_wall(0,   240, 240, 240);
  add_wall(240, 240, 240, 0);
  add_wall(240, 0,   0,   0);

  var sb_p = new StringBuilder();
  var sb_l = new StringBuilder();

  var ball = levels[_game_mode][level].b;

  set_ball(v_(ball.x, ball.y), 10.0, 1.0 / 10.0);

  var walls = levels[_game_mode][level].w;

  var img_lt_rb = "background: url(" + img_l + ") 0px 0px no-repeat;";
  var img_lb_rt = "background: url(" + img_l + ") 0px -60px no-repeat;";
  var img_l_r = "background: url(" + img_l + ") 0px -180px no-repeat;";
  var img_t_b = "background: url(" + img_l + ") 0px -120px no-repeat;";

  for (var i = 0; i < walls.length; ++i) {
    var w = walls[i];    

    if (!w)
      continue;

    if (w.l == 60) {
      if (w.d == 0) {
        add_wall(w.x, w.y, w.x + 60, w.y + 60);
        sb_p.appendList(
          "<div class='l' style='", img_lt_rb, "left: ", w.x, "px; top: ", w.y, "px;'></div>");
        sb_l.appendList(
          "<div class='l' style='", img_lb_rt, "left: ", (240 - w.y - 60), "px; top: ", w.x, "px;'></div>");
      } else if (w.d == 1) {
        add_wall(w.x, w.y + 60, w.x + 60, w.y);

        sb_p.appendList(
          "<div class='l' style='", img_lb_rt, "left: ", w.x, "px; top: ", w.y, "px;'></div>");
        sb_l.appendList(
          "<div class='l' style='", img_lt_rb, "left: ", (240 - w.y - 60), "px; top: ", w.x, "px;'></div>");
      } else if (w.d == 2) {
        add_wall(w.x, w.y + 30, w.x + 60, w.y + 30);

        sb_p.appendList(
          "<div class='l' style='", img_l_r, "left: ", w.x, "px; top: ", w.y, "px;'></div>");
        sb_l.appendList(
          "<div class='l' style='", img_t_b, "left: ", (240 - w.y - 60), "px; top: ", w.x, "px;'></div>");
      } else if (w.d == 3) {
        add_wall(w.x + 30, w.y, w.x + 30, w.y + 60);

        sb_p.appendList(
          "<div class='l' style='", img_t_b, "left: ", w.x, "px; top: ", w.y, "px;'></div>");
        sb_l.appendList(
          "<div class='l' style='", img_l_r, "left: ", (240 - w.y - 60), "px; top: ", w.x, "px;'></div>");
      }
    }
  }

  var dots_count = 0;
  var dots = levels[_game_mode][level].d;
  for (var i = 0; i < dots.length; ++i) {
    var d = dots[i];
    
    if (!d)
      continue;    

    if (d.x > 600) {
      var dx = d.x - 600;

      add_attractor(dx, d.y, 30000);      

      sb_p.appendList("<img id='dot", i, "p' src='dot.gif' width='20' height='20' style='background: transparent url(", img_dev, ") no-repeat -20px 0px; position: absolute; left: ", (dx - 10), "px; top: ", (d.y - 10), "px;' />");
      sb_l.appendList("<img id='dot", i, "l' src='dot.gif' width='20' height='20' style='background: transparent url(", img_dev, ") no-repeat -20px 0px; position: absolute; left: ", (240 - d.y - 10), "px; top: ", (dx - 10), "px;' />");
    } else if (d.x > 300) {          
      var dx = d.x - 300;

      add_attractor(dx, d.y, -30000);
        
      sb_p.appendList("<img id='dot", i, "p' src='dot.gif' width='20' height='20' style='background: transparent url(", img_dev, ") no-repeat 0px 0px; position: absolute; left: ", (dx - 10), "px; top: ", (d.y - 10), "px;' />");
      sb_l.appendList("<img id='dot", i, "l' src='dot.gif' width='20' height='20' style='background: transparent url(", img_dev, ") no-repeat 0px 0px; position: absolute; left: ", (240 - d.y - 10), "px; top: ", (dx - 10), "px;' />");
    } else {
      ++dots_count;
         
      add_trigger(d.x, d.y, 4.0, i);

      sb_p.append("<img id='dot" + i + "p' src='imgs/dot.png' width='8' height='8' style='position: absolute; left: " + (d.x - 4) + "px; top: " + (d.y - 4) + "px;' />");
      sb_l.append("<img id='dot" + i + "l' src='imgs/dot.png' width='8' height='8' style='position: absolute; left: " + (240 - d.y - 4) + "px; top: " + (d.x - 4) + "px;' />");
    }
  }

  _triggers_left = dots_count;
  
  sb_p.appendList(
    "<div id='ball-p' class='ball'><img src='", img_ball, "' width='20' height='20'/></div>");
  sb_l.appendList(
    "<div id='ball-l' class='ball'><img src='", img_ball, "' width='20' height='20'/></div>");

  $("#field-profile").get(0).innerHTML = sb_p.toString();
  $("#field-landscape").get(0).innerHTML = sb_l.toString();

  _ball_l = null;
  _ball_p = null;
    
  sync_simulator();

  $("#btn-tap").css("display", "block");
  $("#btn-tap-img").attr("src", img_tap);
  $("#tap-score").get(0).innerHTML = "loading scores";
  $.post("score.php", 
    { seed: ++_ajax_seed, level: _current_level[_game_mode], mode: _game_mode }, function(xml) {
      var seed = $(xml).attr("s") * 1;
      var n = $(xml).attr("n");
      var kicks = $(xml).attr("k") * 1;
      var flips = $(xml).attr("f") * 1;

      if (seed == _ajax_seed) {
        if (n && n.length) {
          _hi_flips = flips;
          _hi_kicks = kicks;

          var tip = "beat this. less is better.";
          var tip_rnd = Math.random();
          if (tip_rnd < 0.333)
            tip = "could you do in less?";
          else if (tip_rnd < 0.666)
            tip = "improve this!";

          $("#tap-score").get(0).innerHTML = flips + " flips / " + kicks + " kicks<br/>by " + $('<div/>').text(n).html() + "<div id='tap-info'>" + tip + "</div>";
        } else {
          _hi_flips = 10000;
          _hi_kicks = 10000;

          $("#tap-score").get(0).innerHTML = "be the first to<br/>get the topscore!";
        }
      }
    });

  $(".btn-kick").css("opacity", "1");
  _gravity_kick_ready = true;  

  set_on_trigger(on_simulator_trigger);

  if (_current_level[_game_mode] > 0)
    $(".btn-prev").css("opacity", "1");
  else
    $(".btn-prev").css("opacity", "0.2");

  if (_current_level[_game_mode] < _max_level[_game_mode])
    $(".btn-next").css("opacity", "1");
  else
    $(".btn-next").css("opacity", "0.2");
}

function update_simulator() {
  step_simulation(0.05);

  sync_simulator();
}

var _simulator_timer;

function stop_simulator() {
  if (_simulator_timer) {
    clearInterval(_simulator_timer);

    _simulator_timer = null;
  }
}

function start_simulator() {
  $("#btn-tap").css("display", "none");

  _simulator_timer = setInterval(update_simulator, 50);
}

var _value_cache = [];

function get_v(v) {
  var r = Math.floor(v);

  var c = _value_cache[r];

  if (!c) {
    c = r + "px";
    _value_cache[r] = c;
  }
    
  return c;
}


function sync_simulator() {
  if (_ball.c.x < 0 || _ball.c.x > 240 || _ball.c.y < 0 || _ball.c.y > 240)
    set_ball(v_(120.0, 120.0), 10.0, 1.0 / 10.0);
    
  if (_orientation == "profile") {
    if (!_ball_p)
      _ball_p = document.getElementById("ball-p");
    var b = _ball_p;

    b.style.left = get_v(_ball.c.x - 10.0);
    b.style.top = get_v(_ball.c.y - 10.0);
  } else {
    if (!_ball_l)
      _ball_l = document.getElementById("ball-l");
    var b = _ball_l;

    b.style.left = get_v(240.0 - _ball.c.y - 10.0);
    b.style.top = get_v(_ball.c.x - 10.0);
  }
}

var flipped = false;

$(function() {
  // Begin images preloading.
  $(document.createElement('img')).bind('load', function() {
    if(preload_init[0]) {
      this.src = preload_init.shift();
    } else {
      $("#brand").animate({opacity: 1}, 1500, function() {
        setTimeout(function() {
          $("#brand").animate({opacity: 0}, 1500, function() {
            $("#logo").animate({opacity: 1}, 1000, function() {
              $("#brand").css("display", "none");
            });
          });
        }, 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("force");
   
           window.scrollTo(0, 1);
          }, 300);
        }
      }).trigger('load');
    }
  }).trigger('load');

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

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

    $(".btn-kick").css("display", "");

    _game_mode = 0;

    begin_level();
    
    return false;
  });

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

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

    $(".btn-kick").css("display", "none");

    _game_mode = 1;

    begin_level();
    
    return false;
  });

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

    return false;
  });

  $("#btn-tap").click(function() {
    if (_current_level[_game_mode] >= _levels[_game_mode])
      return false;

    start_simulator();

    return false;
  });

  $(".btn-kick").click(gravity_kick);

  $(".btn-reset").click(function() {
    stop_simulator();

    initialize_simulator(_current_level[_game_mode]);
  });

  $(".btn-menu").click(function() {
    stop_simulator();

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

      $("#logo").animate({opacity: 1}, 400);
    });
  });

  $(".btn-prev").click(function() {
    if (_current_level[_game_mode] > 0) {
      stop_simulator();
    
      --_current_level[_game_mode];

      initialize_simulator(_current_level[_game_mode]);
    }
  });

  $(".btn-next").click(function() {
    if (_current_level[_game_mode] < _max_level[_game_mode]) {
      stop_simulator();

      ++_current_level[_game_mode];

      initialize_simulator(_current_level[_game_mode]);
    }
  });

  $("#help-container").click(function() {
    createCookie("rulesShown", "1", 365);

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

  $("#btn-go").click(function() {
    $("#grats-container").animate({opacity: 0}, 400, function() {
      $.post("score.php", 
        { seed: ++_ajax_seed, 
          level: _current_level[_game_mode] - 1, 
          mode: _game_mode,
          name: $("#grats-name").val(),
          flips: _flips,
          kicks: _kicks }, function(xml) {});
  
      $("#grats-container").css("display", "none");

      initialize_simulator(_current_level[_game_mode]);
    });
  });

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

  if (is_iphone) {
    window.onorientationchange = function() {
      var orientation = window.orientation;
      switch(orientation) {
        case 0:
          updateLayout("profile");
          break;
        case 90:
          updateLayout("landscape");
          break;
        case -90:  
          updateLayout("landscape");
          break;
      }
    }
  }

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

    $(".btn-flip").css("display", "block").click(function() {
      ++_flips;

      flipped = !flipped;

      $("#field-profile").css("display", flipped ? "none" : "block");
      $("#field-landscape").css("display", flipped ? "block" : "none");

      if (!flipped) {
        _gravity = v_(0.0, 11.0);
        _orientation = "profile";
      }
      else {
        _gravity = v_(11.0, 0.0);
        _orientation = "landscape";
      }

      sync_simulator();
    });
  } else
    $(".btn-flip").css("display", "none");

  _max_level[0] = readCookie("max_level");
  _current_level[0] = readCookie("current_level");
  _max_level[1] = readCookie("max_level_adv");
  _current_level[1] = readCookie("current_level_adv");

  for (var j = 0; j < 2; ++j)
    for (var i = 0; i < levels[j].length; ++i)
      if (levels[j][i])
        ++_levels[j];
  
  for (var i = 0; i < 2; ++i) {
    _max_level[i] *= 1;
    _current_level[i] *= 1;
    
    if (isNaN(_max_level[i]) || !_max_level[i]) _max_level[i] = 0;
    if (isNaN(_current_level[i]) || !_current_level[i]) _current_level[i] = 0;
    if (_current_level[i] > _max_level[i]) _current_level[i] = _max_level[i];
  }  

  $("#grats-name").val("nickname");  

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