// Copyright 2009 Google Inc.  All Rights Reserved.

/**
 * @fileoverview Global functions for mobile.google.com.
 *
 * mobile.google.com product pages are primarily controlled by
 * bits and notbits. Any element with class bit-{{platform}}
 * will be shown when {{platform}} is selected. Any element with
 * class notbit-{{platform}} will be hidden when {{platform}} is
 * selected.
 *
 * Information about the user's selection is stored in a cookie
 * that persists while the user is navigating among the pages. If
 * a platform is specified in the document hash (via #p={{platform}}),
 * the cookie is overridden. Every page automatically toggles the
 * bits and notbits on the document ready state.
 */


/**
 * Create the mgc namespace.
 */
var mgc = mgc || {};


/**
 * A class to store a session on MGC.
 * @constructor
 */
mgc.session = function() {

  this.current_platform = 'default';
  this.current_product = '';
  this.current_country = 'us';
  this.current_language = 'en';
  this.user_chose_phone = false;

  // Initialize an object to contain handles to the UI of mgc.
  this.uio = {};

  this.uio.phone_selector = {};
  this.uio.stp_hook = {};
  this.uio.stp_widget = {};

  this.current_platform = this.getPlatform();
  this.user_chose_phone = this.getWhetherHasChosenPhone();

  /*
   * Don't autodetect the user's location, for now.
   *
  if (typeof(google.loader.ClientLocation) != 'undefined') {
    this.current_country = google.loader.ClientLocation.address.country_code;
  }
  *
  */

};


/**
 * Sets the current product for the session.
 * @param {string} productId The id of the product.
 */
mgc.session.prototype.setCurrentProduct = function(productId) {
  this.current_product = productId;
};


/**
 * Changes the hook to a function that sets STP message by platform
 * and redraws the page UI.
 * @param {object} config A configuration object containing a map of
 *    platforms to a list containing a message and a hash.
 *    e.g.: 'platform_id': ['message', 'hash']
 */
mgc.session.prototype.setStpMessageByPlatform = function(config) {

  var config = config;

  var changeTheMessage = function() {
    if (config[mgc_session.current_platform]) {
      var message =  config[mgc_session.current_platform][0];
      var hash =  config[mgc_session.current_platform][1];
    } else {
      var message =  config['default'][0];
      var hash =  config['default'][1];
    }
    mgc_session.uio.stp_hook.changeStpMessage(message, hash);
  };

  // Change the hook of the phone selector to change the message.
  this.uio.phone_selector.menuChangeHook = changeTheMessage;
  changeTheMessage();

};


/**
 * Gets the current platform based on, in order: URL hash, cookie.
 * @return {string} The id of the current platform.
 */
mgc.session.prototype.getPlatform = function() {
  var search = window.location.hash;
  var regex = new RegExp('p=([^\&]*)');
  var results = regex.exec(search);
  if (results != null && this.isValidPlatform(results[1])) {
    this.savePlatform(results[1]);
    return results[1];
  } else if (results && results[1] != null) {
    this.savePlatform('default');
    return 'default';
  }

  var search = document.cookie;
  var regex = new RegExp('mgc.platform=([^;]*)');
  var results = regex.exec(search);
  if (results != null && this.isValidPlatform(results[1])) {
    this.savePlatform(results[1]);
    return results[1];
  }

  this.savePlatform('default');
  return 'default';
};


/**
 * Saves a platform into the cookie and session object.
 * @param {string} platformId The id of the platform.
 */
mgc.session.prototype.savePlatform = function(platformId) {

  var hash = window.location.hash;
  hash = hash.replace("#", "");
  hash = hash.replace(new RegExp('p=([^\&]*)'), "p=" + platformId);
  window.location.hash = hash || "#p=" + platformId;

  this.current_platform = platformId;

  var expiry = new Date();
  var urlTruncated = location.href.substring(
      location.href.lastIndexOf('://') + 3,location.href.length);
  var cookiePath = urlTruncated.substring(urlTruncated.indexOf('/'),
      urlTruncated.lastIndexOf('/') + 1);

  expiry.setTime(expiry.getTime() + (24*60*60*1000));
  document.cookie = 'mgc.platform=' + platformId + ';path=' + cookiePath + ';expires=' + expiry.toGMTString() + ';';
};

/**
 * Determines whether or not the current user has made a phone selection,
 * based on the cookie and the session object.
 * @return {boolean} Whether or not the user has chosen a phone.
 */
mgc.session.prototype.getWhetherHasChosenPhone = function() {
  var search = document.cookie;
  var regex = new RegExp('mgc.user_chose_phone=([^;]*)');
  var results = regex.exec(search);
  if (results != null) {
    return true;
  }
  return false;
};

/**
 * Get the two-letter country code for STP based on IP geolocation.
 * @return {string} The two-letter country code for STP.
 */
mgc.session.prototype.getLanguageFromGoogle = function() {
};

/**
 * Determines whether or not the platform specified is a valid platform.
 * @param {string} platformId The id of the platform.
 * @return {boolean} Whether or not the platform is valid.
 */
mgc.session.prototype.isValidPlatform = function (platformId) {
  if (platformId in MGC_CONFIG.platforms) {
    return true;
  } else {
    return false;
  }
};


/**
 * Hides all elements on the page with class "bit".
 * @param {string} bitClassName Unused.
 */
mgc.hideBits = function(bitClassName) {
  jQuery('.bit').hide();
};


/**
 * Shows all elements on the page with class "bit-{{name}}.
 * Shows all elements on the page with class "notbit".
 * Hides all elements on the page with class "notbit-{{name}}".
 * @param {string} bitClassName The identifier for the bit to toggle.
 */
mgc.showBits = function(bitClassName) {
  jQuery('.bit-' + bitClassName).show();
  jQuery('.notbit').show();
  jQuery('.notbit-' + bitClassName).hide();
};


/**
 * Draws the UI for a platform and saves the platform to the session object.
 * @param {string} platformId The id of the platform.
 */
mgc.uiBitToggle = function(platformId) {
  mgc.hideBits(platformId);
  mgc.showBits(platformId);
  mgc_session.savePlatform(platformId);
};

var checkInArray = function(tArray, search_phrase) {
    for (var i = 0; i < tArray.length; i++) {
      if (search_phrase == tArray[i]) {
        return true;
      }
    }
  return false;
};


/**
 * Returns an list containing information about the products for a specified
 *     platform.
 * @param {string} platformId The id of the platform or 'all_products'.
 * @return {list} A list of product objects.
 */
mgc.getProductsInPlatform = function(platformId) {

  var platform_list = [];

  for (var product in MGC_CONFIG.products) {
    if (checkInArray(MGC_CONFIG.products[product].platforms, platformId) ||
        platformId == 'all_products') {
      if (MGC_CONFIG.products[product].platforms.length > 0) {
        platform_list.push(product);
      }
    }
  }
  return platform_list;
};


/**
 * Gets information about a specified product.
 * @param {string} productId The id of the product.
 * @return {object} A computed object containing information about the product.
 */
mgc.getProductInfo = function(productId) {
  var info = MGC_CONFIG.products[productId];

  info['id'] = productId;
  if (checkInArray(MGC_CONFIG.hero_products, info['id'])) {
    info['is_hero'] = true;
  } else {
    info['is_hero'] = false;
  }
  if (mgc_session.current_platform in MGC_CONFIG.new_products &&
      checkInArray(MGC_CONFIG.new_products[mgc_session.current_platform],
      info['id'])) {
    info['is_new'] = true;
  } else {
    info['is_new'] = false;
  }
  return info;
};


/**
 * Gets all the platforms that the specified product is available for.
 * @param {string} productId The id of the product.
 * @return {object} An object containing information about the platforms.
 */
mgc.getPlatformsByProduct = function(productId) {
  var info = MGC_CONFIG.products[productId].platforms;
  var platforms = {};

  for (var platform in info) {
    var platform_id = info[platform];

    if (typeof(platform_id) == 'string') {
      platforms[platform_id] = {};
      platforms[platform_id]['name'] = MGC_CONFIG.platforms[platform_id].name;
      platforms[platform_id]['id'] = platform_id;
    }
  }
  return platforms;
};


/**
 * Gets all the platforms.
 * @return {object} An object containing information about the platforms.
 */
mgc.getPlatformsInCountry = function() {
  var info = MGC_CONFIG.platforms;

  for (var platform in info) {
    info[platform].id = platform;
  }
  return info;
};

mgc.drawProductTiles = function(divId, platformId, config) {

  if (config.show_all_for_default && platformId == 'default') {
    var products = mgc.getProductsInPlatform('all_products');
  } else {
    var products = mgc.getProductsInPlatform(platformId);
  }

  var divEl = document.getElementById(divId);
  divEl.innerHTML = '';

  for (var i=0; i < products.length; i++) {
    var info = mgc.getProductInfo(products[i]);

    if ((typeof(info) != 'undefined') && !(info.is_hero && (config.dont_show_hero_products == true))) {

      var newdiv = document.createElement('li');

      newdiv.className = info.id;

      if (!config.no_click_on_li) {
        var clickHandler = function(infoId, platformId) {
          return function() {
            window.location = infoId + '.html#p=' + platformId;
          }
        };
        newdiv.style.cursor = 'pointer';
        newdiv.onclick = clickHandler(info.id, platformId);
      }

      if (info.id == 'more') {
        var icon = 'http://www.google.com/clear.gif';
      } else {
        var icon = '/mobile/images/ui/icons/' + info.id + '.gif';
      }

      // Determine the root directory so we can use this code on
      // both the homepage and on a product page.
      var urlTruncated = location.href.substring(
          location.href.lastIndexOf('://') + 3,location.href.length);
      var rootDir = urlTruncated.substring(urlTruncated.indexOf('/'),
          urlTruncated.lastIndexOf('/') + 1);

      if (rootDir.indexOf('products') == -1) {
        rootDir += 'products/';
      }
      
      // interim fix: determine if this is in 'navigation' subdirectory, if so, make the href relative
      if (rootDir.indexOf('navigation') != -1 ) {
        rootDir = '../products/';
      }
      
      newdiv.innerHTML = '<img src="' + icon + '">'
        + '<a href="' + rootDir + info.id + '.html#p=' + platformId + '">'
        + info.name + '</a>';

      if (config.show_description) {
        newdiv.innerHTML += '<span>' + info.desc + '</span>';
      }
      if (info.is_new) {
        newdiv.innerHTML += '<span class="snew">New!</span>';
      }

      if (config.click_callback) {
        newdiv.getElementsByTagName('a')[0].href = '#';
        newdiv.getElementsByTagName('a')[0].onclick = 'mgc.showBits(' + info.id + ')';
      }

      divEl.appendChild(newdiv);

    }
  }
};

mgc.media = function(id, content) {
  this.container = document.getElementById(id);
  var videoUrl = content.videos[0];
  this.drawVideo(videoUrl);
};

mgc.media.prototype.drawVideo = function(videoUrl) {
  this.container.innerHTML = '<ul class="media">'
  + '<li><object width="320" height="240"><param name="wmode" value="transparent"></param><param name="movie" value="' + videoUrl + '&hl=en&fs=1&showinfo=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="' + videoUrl + '&hl=en&fs=1&showinfo=0" type="application/x-shockwave-flash" wmode="transparent" allowscriptaccess="always" allowfullscreen="true" width="320" height="240"></embed></object>'
  + '</ul>';
};

mgc.phoneDrop = function(phoneDropEl, productId) {
  this.session = mgc_session;
  this.main_list = document.getElementById(phoneDropEl);
  this.initChooser();
  this.list_to_append = this.main_list.getElementsByTagName('ul')[0];
  this.selected_element = this.main_list.getElementsByTagName('li')[0];
  this.selected_a = this.main_list.getElementsByTagName('a')[0];
  this.productId = productId;

  this.menuChangeHook = function() {};

  this.main_list.onmouseover = this.showMenu(this);
  this.main_list.onmouseout = this.hideMenu(this);

  this.drawOptions();

  if (this.session.current_platform != 'default' || this.session.user_chose_phone) {
    this.setSelectedItem(this.session.current_platform);
    this.menuChangeHandler(this, this.session.current_platform);
  }

  // Link back to the main mgc session object.
  if (typeof(mgc_session) != 'undefined') {
    mgc_session.uio.phone_selector = this;
  }

};

mgc.phoneDrop.prototype.showMenu = function(me) {
  return function() {
    me.list_to_append.style.display = 'block';
  }
};

mgc.phoneDrop.prototype.hideMenu = function(me) {
  return function() {
    me.list_to_append.style.display = 'none';
  }
};

mgc.phoneDrop.prototype.initChooser = function() {
  this.main_list.innerHTML = ''
    + '<li class="outer"><a href="#">'
    + '<img src="/mobile/images/ui/phones/choose-small.gif">Choose your phone</a>'
    + '<ul></ul>';
};

mgc.phoneDrop.prototype.setSelectedItem = function(itemId) {
  var new_active = document.getElementById('popt-' + itemId).getElementsByTagName('a')[0];
  this.selected_a.innerHTML = new_active.innerHTML;
  if (itemId == 'default') {
    this.selected_a.getElementsByTagName('img')[0].src = '/mobile/images/ui/phones/default-small.gif';
  }
};


mgc.phoneDrop.prototype.menuChangeAction = function() {

  // Do something with the extended menuChangeHook.
  this.menuChangeHook();

  // Toggle the bits.
  mgc.uiBitToggle(mgc_session.current_platform);

  // Action on all inside pages.
  mgc.drawProductTiles('more-products', mgc_session.current_platform, {
      'show_description': false,
      'show_all_for_default': true,
      'dont_show_hero_products': true});

  // Set the help center links.
  mgc.setHelpCenters(mgc_session.current_platform, mgc_session.current_product);

};

mgc.phoneDrop.prototype.changePlatform = function(newPlatformId) {
  this.menuChangeHandler(this, newPlatformId)();
};

mgc.phoneDrop.prototype.menuChangeHandler = function(me, newPlatformId) {
  return function() {
    me.list_to_append.style.display = 'none';
    me.setSelectedItem(newPlatformId);
    mgc_session.savePlatform(newPlatformId);
    me.menuChangeAction();
    var expiry = new Date();
    expiry.setTime(expiry.getTime() + (24 * 60 * 60 * 1000));
    var urlTruncated = location.href.substring(
        location.href.lastIndexOf('://') + 3,location.href.length);
    var cookiePath = urlTruncated.substring(urlTruncated.indexOf('/'),
        urlTruncated.lastIndexOf('/') + 1);
    document.cookie = 'mgc.user_chose_phone=true;path=' + cookiePath + ';expires=' + expiry.toGMTString() + ';';
    me.session.user_chose_phone = true;
  }
};

mgc.phoneDrop.prototype.drawOptions = function() {
  if (this.productId == 'all_platforms') {
    var platforms = mgc.getPlatformsInCountry();
  } else {
    var platforms = mgc.getPlatformsByProduct(this.productId);
  }

  for (var i in platforms) {
    var info = platforms[i];

    var newdiv = document.createElement('li');
    newdiv.id = 'popt-' + info.id;
    newdiv.style.cursor = 'pointer';
    newdiv.onclick = this.menuChangeHandler(this, info.id);

    var newa = '<a href="#p=' + info.id + '">'
        + '<img src="/mobile/images/ui/phones/' + info.id + '-small.gif">'
        + info.name + '</a>';

    newdiv.innerHTML = newa;

    if (info.id == 'default') {
      newdiv.getElementsByTagName('img')[0].src = 'http://www.google.com/clear.gif';
    }

    this.list_to_append.appendChild(newdiv);
  }
};

mgc.hide = function(divId) {
  document.getElementById(divId).style.display = 'none';
};

mgc.feeder = function(idToFill) {
  this.idToFill = idToFill;
  this.feedData = '';
};

mgc.feeder.prototype.handleBloggerFeed = function(json) {

  var truncate = function(str, limit) {
    var bits, i;
    bits = str.split('');
    if (bits.length > limit) {
      for (i = bits.length - 1; i > -1; --i) {
        if (i > limit) {
          bits.length = i;
        }
        else if (' ' === bits[i]) {
          bits.length = i;
          break;
        }
      }
      bits.push('...');
    }
    return bits.join('');
  };

  var output = '';

  for (var i = 0; i < 3; i++) {
    var entry = json.feed.entry[i]
    var postTitle = entry.title.$t;
    postTitle = truncate(postTitle, 55);
    var postDate = entry.published.$t.substr(0,10);
    var postUrl;

    for (var k = 0; k < entry.link.length; k++) {
      if (entry.link[k].rel == 'alternate') {
        postUrl = entry.link[k].href;
        break;
      }
    }
    output += '<li>' + postDate + ' - <a href="'+ postUrl +
      '">'+ postTitle + '</a>';
  }

  this.feedData = output;
  this.drawFeed();
};


mgc.feeder.prototype.drawFeed = function() {
  document.getElementById(this.idToFill).innerHTML = this.feedData;
};


mgc.navbar = function() {
};


mgc.navbar.handleClick = function(tabId) {
  var tab = document.getElementById(tabId);
  var target = tab.getElementsByTagName('a')[0].href;
  tab.onclick = window.location = target;
  jQuery('#navbar').find('li').removeClass('selected');
  tab.className = 'selected';
};


/**
 * Creates an instance of the Analytics tracker and sends a trackPageview.
 * Also tags all outgoing links, determined by links that start with "http"
 * with Analytics event tracking.
 */
mgc.analyticsHandler = function() {
  this.ua = 'UA-18047-1';

  if (typeof(_gat) == 'undefined') {
    return null;
  }

  var tracker = _gat._getTracker(this.ua);
  if (typeof(tracker) == 'undefined') {
    return null;
  }

  var path = document.location.pathname;
  var dynamicCp = path.match(/.+?mobile\//gi);

  if (!dynamicCp) {
    tracker._setCookiePath('/mobile/');
  } else {
    tracker._setCookiePath(dynamicCp);
  }
  tracker._setAllowAnchor(true);
  tracker._trackPageview();
  jQuery('a').each(function() {
      var url = jQuery(this).attr('href');
      if (typeof(url) != 'undefined' && url.indexOf('http://') == 0) {
      var outgoingTag = url.toString();
      jQuery(this).click(function() {
        tracker._trackEvent('Outgoing click', 'Auto-tagged', '" + outgoingTag + "');
        });
      }
  });
};

mgc.smallTour = function(config) {
  this.imageList = config.imageList;
  this.captionEl = document.getElementById(config.captionId);
  this.imageEl = document.getElementById(config.imageId);
  this.currentImageIndex = 0;
  this.nextEl = document.getElementById(config.nextId);
  this.prevEl = document.getElementById(config.prevId);
  this.setImage(this.currentImageIndex);
};


mgc.smallTour.prototype.setImage = function(imageIndex) {
  this.imageEl.src = this.imageList[imageIndex][1];
  this.currentImageIndex = imageIndex;
  this.setArrows();
};


mgc.smallTour.prototype.setCaption = function(imageIndex) {
  this.captionEl.innerHTML = this.imageList[imageIndex][0];
};


mgc.smallTour.prototype.setArrows = function() {
  if (this.currentImageIndex + 1 >= this.imageList.length) {
    this.nextEl.onclick = this.setImageClickHandler(this, 0);
  } else {
    this.nextEl.onclick = this.setImageClickHandler(this, this.currentImageIndex + 1);
  }
  if (this.currentImageIndex - 1 == -1) {
    this.prevEl.onclick = this.setImageClickHandler(this, this.imageList.length - 1);
  } else {
    this.prevEl.onclick = this.setImageClickHandler(this, this.currentImageIndex - 1);
  }
};


mgc.smallTour.prototype.setImageClickHandler = function(me, imageIndex) {
  return function() {
    me.setImage(imageIndex);
    me.setCaption(imageIndex);
  }
};


mgc.feedFiller = function(feedUrl) {
  jQuery(document).ready(function() {
    if (!gweb.feed) {
      return;
    }

    var loadData = function(data) {
      for (var item in data) {
        var current = data[item];
        jQuery('#' + current.rowTitle).html(current.content);
      }
    }

    gweb.feed.loadSpreadsheet(loadData, feedUrl, false);
  });
};

mgc.getHelpCenterUrl = function(platformId, productId) {
  return MGC_CONFIG.help_centers[productId][platformId] ||
      "http://www.google.com/support/mobile/";
};


mgc.getHelpCenterName = function(platformId, productId) {
  if (MGC_CONFIG.help_centers[productId][platformId]) {
    return 'Help Center for ' + MGC_CONFIG.products[productId]['name'];
  } else {
    return 'Mobile Help Center';
  }
};


/**
 * Rewrites the URL for the Help Center on the page.
 * @param {string} platformId The id of the platform.
 * @param {string} productId The id of the product
 */
mgc.setHelpCenters = function(platformId, productId) {
  var hcEl = jQuery('#help_center').find('a');
  var hc_url = mgc.getHelpCenterUrl(platformId, productId);
  var hc_name = mgc.getHelpCenterName(platformId, productId);
  hcEl.attr('href', hc_url);
  hcEl.html(hc_name);
};



mgc.mediaTour = function(ulId) {
  this.ulId = ulId;
  this.init();
};


/**
 * Draws a video object based on the rel attribute of li elements with class
 * "video".
 */
mgc.mediaTour.prototype.setMedia = function() {
  jQuery('ul.mgc-media li.video').each(function() {

    var $html = jQuery(this).html();

    if ($html.indexOf('span') == -1) {
      jQuery(this).html('<span></span>');
    }

    if ($html.indexOf('object') == -1) {
      var videoUrl = jQuery(this).attr('rel');
      jQuery(this).prepend('<object width="320" height="240"><param name="wmode" value="transparent"></param><param name="movie" value="' + videoUrl + '&hl=en&fs=1&showinfo=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="' + videoUrl + '&hl=en&fs=1&showinfo=0" type="application/x-shockwave-flash" wmode="transparent" allowscriptaccess="always" allowfullscreen="true" width="320" height="240"></embed></object>');
    }

  });
};


/**
 * Initializes the mgc.mediaTour object by creating the navigation arrows.
 */
mgc.mediaTour.prototype.init = function() {

  jQuery('#' + this.ulId + ' li:first').show();
  this.setMedia();

  var $arrowLeft = jQuery('<a href="javascript:void 0;" class="arrow left"><img src="/mobile/images/enterprise/left.png"></a>');
  var $arrowRight = jQuery('<a href="javascript:void 0;" class="arrow right"><img src="/mobile/images/enterprise/right.png"></a>');

  $arrowLeft.insertBefore(jQuery('#' + this.ulId + ' li span'));
  $arrowRight.insertBefore(jQuery('#' + this.ulId + ' li span'));

  var me = this;
  jQuery('#' + this.ulId + ' a.right').click(function() { me.switchActive('right'); });
  jQuery('#' + this.ulId + ' a.left').click(function() { me.switchActive('left'); });

};


/**
 * A handle to the switchActive function.
 * @param {object} me The mgc.mediaTour object.
 * @param {'right'|'left'} direction The direction to advance the show.
 */
mgc.mediaTour.prototype.switchHandler = function(me, direction) {
  return function() {
    me.switchActive(direction);
  }
};


/**
 * Sets the class of the next slide to active and removes the active class
 * from the previous slide.
 * @param {'right'|'left'} direction The direction to advance the show.
 */
mgc.mediaTour.prototype.switchActive = function(direction) {
  var $active = jQuery('#' + this.ulId + ' li.active');
  var $caption = jQuery('#' + this.ulId + ' li.active span');

  if (direction == 'right') {
    var $next = $active.next().length ? $active.next()
        : jQuery('#' + this.ulId + ' li:first');
  } else {
    var $next = $active.prev().length ? $active.prev()
        : jQuery('#' + this.ulId + ' li:last');
  }

  $next.addClass('active');
  $active.removeClass('active');
};


/**
 * Because this is the base JavaScript file for all of mobile.google.com,
 * let's set the initialization tasks for each page load right in this file.
 */
jQuery(document).ready(function() {

  // Apply a fix for the navbar for IE6.
  jQuery('#more-link').hover(
    function() {
      jQuery(this).addClass('over');
    }, function() {
      jQuery(this).removeClass('over');
    }
  );

  // Toggle the bits on the current page based on the selected platform.
  mgc.uiBitToggle(mgc_session.current_platform);

  // Actions for if the page is a product page.
  if (mgc_session.current_product) {
    // Set the Help Center link on the current page based on the selected platform.
    mgc.setHelpCenters(mgc_session.current_platform, mgc_session.current_product);
    // Render the media.
    mgc.mediaTour.prototype.setMedia();
  }

});

