var Heyzap = function(eplayer_div_id, o_params){
  var player_div_id = eplayer_div_id;
  var previous_location = null;
  var previous_cmd = null;
  var lightboxDisplayed = false;
  var heyzap_domain = "http://www.heyzap.com";
  var current_game = null;
  var auto_play = false;
  var embed_key = null;
  var noparent = null;

  var mini_watcher_activated = null;
  if(o_params){
    current_game = o_params.game;
    auto_play = o_params.play;
    noparent = o_params.noparent;
    embed_key = o_params.embed_key;
  }

  this.renderMini = function(d_heyzap_domain, size){
    var height = '194';
    var width = '194';
    var player_div = document.getElementById(eplayer_div_id);

    if (d_heyzap_domain) { heyzap_domain = d_heyzap_domain; }

    var parameters = "";
    if(size == "medium"){
      parameters = '/embed_medium?parent_url='+encodeURIComponent(parent_url());
      if(noparent){
        parameters = '/embed_medium?noparent=true';
      }
      height = "344";
      width = "425";
    }
    else if(size == "300"){
      parameters = '/embed_300?parent_url='+encodeURIComponent(parent_url());
      if(noparent){
        parameters = '/embed_300?noparent=true';
      }
      height = "250";
      width = "300";
    }
    else if(size == "small_dynamic"){
      parameters = '/embed_small?parent_url='+encodeURIComponent(parent_url());
      if(noparent){
        parameters = '/embed_small?noparent=true';
      }
    }
    else{
      parameters = '/embed/mini_embed_190?parent_url='+encodeURIComponent(parent_url());
      if(noparent){
        parameters = '/embed/mini_embed_190?noparent=true';
      }
    }
    if(embed_key){
        parameters = parameters+'&embed_key='+embed_key
    }
    if (current_game){
        parameters = parameters+'&permalink='+current_game;
    }

    if (auto_play){
        parameters = parameters+'&play=true';
    }

    if(player_div){
      player_div.innerHTML = "<iframe id=\"heyzap_iframe\" src=\""+heyzap_domain+parameters+"\" width=\""+width+"\" height=\""+height+"\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" ></iframe>"
      player_div.style.height = height+'px';
      player_div.style.width = width+'px';
    }

    addLoadEvent(call_mini_hash_watcher);
    setTimeout(call_mini_hash_watcher, 5000);
  }

  this.render = function(d_heyzap_domain, esize){
    esize  = esize ? esize : "large";
    var embed_games = esize == "large" ? 'embed_games' : 'embed_games_800';
    var embed_link = esize == "large" ? 'embed' : 'embed_800';
    var player_div = document.getElementById(eplayer_div_id);

    if (d_heyzap_domain) { heyzap_domain = d_heyzap_domain; }

    var parameters = '/'+embed_link+'?parent_url='+encodeURIComponent(parent_url());
    if(current_game){
        if(auto_play){
          parameters = '/games/'+current_game+'?'+embed_link+'=1&parent_url='+encodeURIComponent(parent_url());
        }
        else{
          parameters = '/'+embed_games+'/'+current_game+'?parent_url='+encodeURIComponent(parent_url());
        }
    }
    if(noparent){
      if(current_game){
        if(auto_play){
          parameters = '/games/'+current_game+'?'+embed_link+'=1&noparent=true';
        }
        else{
          parameters = '/'+embed_games+'/'+current_game+'?noparent=true';
        }
      }
      else{
        parameters = '/'+embed_link+'?noparent=true';
      }
    }
    if(embed_key){
        parameters = parameters+'&embed_key='+embed_key
    }

    var height = '650';
    var width = esize == 'large' ? '658' : '808';

    player_div.innerHTML = "<iframe id=\"heyzap_iframe\" src=\""+heyzap_domain+parameters+"\" width=\""+width+"\" height=\""+height+"\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" ></iframe>"
    player_div.style.height = height+'px';
    player_div.style.width = width+'px';

    hash_watcher();
  }

  var parent_url = function(){
    return window.location.href;
  }

  var hash_watcher = function(){
    if(location.hash == previous_location){
      setTimeout(hash_watcher, 300);
      return;
    }
    var iframe_height = get_hash_param(location, "heyzap_height");
    var player_div = document.getElementById(eplayer_div_id);
    var iframe_div = document.getElementById('heyzap_iframe');
    if(iframe_height){
      player_div.style.height = iframe_height+'px';
      if(iframe_div){
        iframe_div.height = iframe_height;
      }
      previous_location = location.hash;
    }

    // remove heyzap_height param
    setTimeout(hash_watcher, 300);
  }

  var get_hash_param = function(url, param_name){
     param_name = param_name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
     var regexS = "[\\?&#]"+param_name+"=([^&#]*)";
     var regex = new RegExp( regexS );
     var results = regex.exec( url );
     if( results == null )
     return null;
     else
     return decodeURIComponent(results[1]);
  }

  var rm_hash_param = function(param_name){
    try{
    var url = new String(location);
    }
    catch(err){
      return null;
    }
    param_name = param_name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regexS = "[\\?&#]"+param_name+"=([^&#]*)";
    var regex = new RegExp( regexS );
    var results = regex.exec( url );
    if( results == null )
    return null;
    else{
      var res = results[0];
      url = url.substr(0, url.indexOf(res));
      if (url.indexOf('#') == -1){
        url += '#hz';
      }
      location.href = url;
    }
  }

  var HeyzapPopup = function(eplayer, embed_key, esize){
    var player_div = eplayer;
    var width = esize == "large" ? 650 : 800;
    this.render = function(d_heyzap_domain){
      if (d_heyzap_domain) { heyzap_domain = d_heyzap_domain; }

      var parameters = '/embed_800?parent_url='+encodeURIComponent(parent_url());
      if(width == 650){
        var parameters = '/embed?parent_url='+encodeURIComponent(parent_url());
      }

      if(embed_key){
          parameters = parameters+'&embed_key='+embed_key
      }

      document.getElementById('hzlightbox').style.width = width+'px';

      player_div.innerHTML = "<iframe src=\""+heyzap_domain+parameters+"\" width=\"800\" height=\"650\" marginwidth=\"0\" marginheight=\"0\" hspace=\"0\" vspace=\"0\" frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" ></iframe>"
      player_div.style.height = '650px';
      player_div.style.width = width+'px';
    }

    var parent_url = function(){
      try{
      return window.location.href;
      }catch(e){
      }
    }
  }

  /*
    Lightbox JS: Adapted from  - http://www.huddletogether.com by Lokesh Dhakar
  */

  var loadingImage = heyzap_domain+'/elightbox/loading-external.gif';
  var closeButton = heyzap_domain+'/elightbox/close-external.png';

  //
  // getPageScroll()
  // Returns array with x,y page scroll values.
  // Core code from - quirksmode.org
  //
  function getPageScroll(){

    var yScroll;

    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
    } else if (document.documentElement && document.documentElement.scrollTop){   // Explorer 6 Strict
      yScroll = document.documentElement.scrollTop;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
    }

    arrayPageScroll = new Array('',yScroll)
    return arrayPageScroll;
  }

  //
  // getPageSize()
  // Returns array with page width, height and window width, height
  // Core code from - quirksmode.org
  // Edit for Firefox by pHaez
  //
  function getPageSize(){

    var xScroll, yScroll;

    if (window.innerHeight && window.scrollMaxY) {
      xScroll = document.body.scrollWidth;
      yScroll = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
      xScroll = document.body.scrollWidth;
      yScroll = document.body.scrollHeight;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
      xScroll = document.body.offsetWidth;
      yScroll = document.body.offsetHeight;
    }

    var windowWidth, windowHeight;
    if (self.innerHeight) {  // all except Explorer
      windowWidth = self.innerWidth;
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      windowWidth = document.documentElement.clientWidth;
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowWidth = document.body.clientWidth;
      windowHeight = document.body.clientHeight;
    }

    // for small pages with total height less then height of the viewport
    if(yScroll < windowHeight){
      pageHeight = windowHeight;
    } else {
      pageHeight = yScroll;
    }

    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth){
      pageWidth = windowWidth;
    } else {
      pageWidth = xScroll;
    }

    arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
    return arrayPageSize;
  }

  //
  // pause(numberMillis)
  // Pauses code execution for specified time. Uses busy code, not good.
  // Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
  //
  function pause(numberMillis) {
    var now = new Date();
    var exitTime = now.getTime() + numberMillis;
    while (true) {
      now = new Date();
      if (now.getTime() > exitTime)
        return;
    }
  }

  //
  // showLightbox()
  // Preloads images. Pleaces new image in lightbox then centers and displays.
  //
  function showLightbox(objLink, esize)
  {
    lightboxDisplayed = true;
    createOverlay();

    // prep objects
    var objOverlay = document.getElementById('hzoverlay');
    var objLightbox = document.getElementById('hzlightbox');
    var objLoadingImage = document.getElementById('hzloadingImage');

    var arrayPageSize = getPageSize();
    var arrayPageScroll = getPageScroll();

    // center loadingImage if it exists
    if (objLoadingImage) {
      objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
      objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
      objLoadingImage.style.display = 'block';
    }

    // set height of Overlay to take up whole page and show
    objOverlay.style.height = (arrayPageSize[1] + 'px');
    objOverlay.style.display = 'block';

    var hz_iframe = document.getElementById('heyzap-div');
    if(!hz_iframe){
      var hz_iframe = document.createElement('div');
      hz_iframe.setAttribute('id', 'heyzap-div');
    }

    var hzpopup = new HeyzapPopup(hz_iframe, embed_key, esize);
    hzpopup.render();

    // center lightbox and make sure that the top and left values are not negative
    // and the image placed outside the viewport
    var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - parseInt(hz_iframe.style.height)) / 2);
    var lightboxLeft = ((arrayPageSize[0] - 20 - parseInt(hz_iframe.style.width)) / 2);

    objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
    objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";

    if (objLoadingImage) {  objLoadingImage.style.display = 'none'; }

    // Hide select boxes as they will 'peek' through the image in IE
    selects = document.getElementsByTagName("select");
        for (i = 0; i != selects.length; i++) {
                selects[i].style.visibility = "hidden";
    }

    objLightbox.style.display = 'block';

    // After image is loaded, update the overlay height as the new image might have
    // increased the overall page height.
    arrayPageSize = getPageSize();
    objOverlay.style.height = (arrayPageSize[1] + 'px');

    objLightbox.appendChild(hz_iframe);
    return false;
  }

  //
  // hideLightbox()
  //
  function hideLightbox() {
    lightboxDisplayed = false;
    // get objects
    objOverlay = document.getElementById('hzoverlay');
    objLightbox = document.getElementById('hzlightbox');

    // hide lightbox and overlay
    objOverlay.style.display = 'none';
    objLightbox.style.display = 'none';

    var hz_iframe = document.getElementById('heyzap-div');
    hz_iframe.parentNode.removeChild(hz_iframe);

    // make select boxes visible
    selects = document.getElementsByTagName("select");
      for (i = 0; i != selects.length; i++) {
      selects[i].style.visibility = "visible";
    }
    // remove heyzap_game
    location.href = change_hash_param(location.href, 'heyzap_game', '');

  }
  var change_hash_param = function(url, param_name, new_value){
    var hash_idx = url.search('#')
    if(hash_idx == -1){
      return url + '#' + param_name + '=' + new_value;
    }

    param_name = param_name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regexS = "[\\?&#]"+param_name+"=([^&#]*)";
    var regex = new RegExp( regexS );
    var results = regex.exec(url.substr(hash_idx));
    if( results == null )
      return url + '&' + param_name + '=' + new_value;
    else{
      var idx = url.search(results[0])
      return (url.substr(0, idx+1) + param_name+'='+ encodeURIComponent(new_value) + url.substr(idx+results[0].length));
    }
  }

  // esize is either large or extra_large widget viersions. Default to extra_large
  this.showGamesPopup = function(permalink, esize){
    if(permalink){
      var new_url = Common.change_hash_param(location.href,'heyzap_game', permalink);
      Common.set_parent_location(new_url);
    }
    showLightbox(this, esize);
  }

  var call_mini_hash_watcher = function(){
    if(mini_watcher_activated){
      return;
    }
    else{
      mini_hash_watcher();
      mini_watcher_activated = true;
    }
  }
  var mini_hash_watcher = function(){
    if(lightboxDisplayed){
      setTimeout(mini_hash_watcher, 300);
      return;
    }

    var game = get_hash_param(location, "heyzap_game");
    var heyzap_cmd = get_hash_param(location, "heyzap_cmd");

    if(heyzap_cmd == previous_cmd && game == previous_location){
      setTimeout(mini_hash_watcher, 300);
      return;
    }

    previous_location = game;
    previous_cmd = heyzap_cmd;

    if(game || heyzap_cmd){
      showLightbox(this);
    }

    setTimeout(mini_hash_watcher, 300);
  }

  function createOverlay(){
    var objBody = document.getElementsByTagName("body").item(0);

    // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
    var objOverlay = document.getElementById('hzoverlay');
    if(objOverlay){
      return
    }
    objOverlay = document.createElement("div");
    objOverlay.setAttribute('id','hzoverlay');
    objOverlay.style.display = 'none';
    objOverlay.style.position = 'absolute';
    objOverlay.style.top = '0';
    objOverlay.style.left = '0';
    objOverlay.style.zIndex = '19990';
    objOverlay.style.width = '100%';
    objBody.insertBefore(objOverlay, objBody.firstChild); // insert at the top

    var arrayPageSize = getPageSize();
    var arrayPageScroll = getPageScroll();

    var objLoadingImageLink = document.createElement("a");
    objLoadingImageLink.setAttribute('href','#');
    objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
    objOverlay.appendChild(objLoadingImageLink);

    var objLoadingImage = document.createElement("img");
    objLoadingImage.src = loadingImage;
    objLoadingImage.setAttribute('id','hzloadingImage');
    objLoadingImage.style.position = 'absolute';
    objLoadingImage.style.zIndex = '20150';
    objLoadingImageLink.appendChild(objLoadingImage);

    // create lightbox div, same note about styles as above
    var objLightbox = document.createElement("div");
    objLightbox.setAttribute('id','hzlightbox');
    objLightbox.style.display = 'none';
    objLightbox.style.position = 'absolute';
    objLightbox.style.zIndex = '20000';
    objBody.insertBefore(objLightbox, objOverlay.nextSibling);

    // create link
    var objLink = document.createElement("a");
    objLink.setAttribute('href','#');
    objLink.setAttribute('title','Click to close');
    objLink.onclick = function () {hideLightbox(); return false;}
    objLightbox.appendChild(objLink);

    // preload and create close button image
    var imgPreloadCloseButton = new Image();

    // if close button image found,
    imgPreloadCloseButton.onload=function(){
      var objCloseButton = document.createElement("img");
      objCloseButton.src = closeButton;
      objCloseButton.setAttribute('id','hzcloseButton');
      objCloseButton.style.position = 'absolute';
      objCloseButton.style.zIndex = '20001';
      objLink.appendChild(objCloseButton);

      return false;
    }
    imgPreloadCloseButton.src = closeButton;
  }

  //
  // addLoadEvent()
  // Adds event to window.onload without overwriting currently assigned onload functions.
  // Function found at Simon Willison's weblog - http://simon.incutio.com/
  //
  function addLoadEvent(func)
  {
    var oldonload = window.onload;
    if (typeof window.onload != 'function'){
        window.onload = func;
    } else {
      window.onload = function(){
      oldonload();
      func();
      }
    }

  }
}
