 // Copyright 2010 Google Inc.  All Rights Reserved.

/**
 * @fileoverview Javascript file for Display Ad Builder example templates
 * gallery.
 * Requires use of http://www.google.com/js/feed.js.
 *
 * @author dave carlsson
 */

/**
 * Namespace for press websites.
 */
var press = press || {};

// "press" website namespace (not specific to twitter directory class).
// Contstants in "press" namespace.
/**
 * Used to add image-free, CSS rounded corners to containers.
 * The HTML that comprises the second part of the implementation and rounds
 * the bottom left and right corners of a container.
 * @const
 * @type {string}
 */
press.ROUND_BOTTOM = '</div>' +
    '<div class="pc-module-round-3"></div>' +
    '</div>';

/**
 * Used to add image-free, CSS rounded corners to containers.
 * The HTML that comprises the first part of the implementation and rounds
 * the top left and right corners of a container.
 * @const
 * @type {string}
 */
press.ROUND_TOP = '<div class="pc-module-round">' +
    '<div class="pc-module-round-3"></div>' +
    '<div class="pc-module-round-content">';

// Static methods in "press" namespace.
/**
 * Removes white space from either side of a text string.
 * @param {string} textToClean Text that may have extra white space on either
 *    side of it.
 * @return {string} Text string without additional white space on either side.
 * @private
 */
press.cleanText_ = function(textToClean) {
  return textToClean.match(/[A-Z].*[a-z]/);
};

/**
 * Converts the display name for each Twitter account into an ID friendly
 * version.
 * @param {string} text The Twitter account name listed in the
 *     Spreadsheet and displayed to the user.
 * @return {string} An HTML ID friendly versin of the display name.
 */
press.textToId = function(text) {
  return text.toLowerCase().replace(/[^a-z0-9]/g, '');
};

/**
 * Press Twitter directory class.
 * Wrapper for all Twitter directory related press site JavaScript.
 * @constructor
 */
press.twitterDirectory = function() {
};

// Constants
/**
 * The text to use for navigation to show all items in the directory.
 * @const
 * @type {string}
 */
press.twitterDirectory.ALL_CATEGORIES = 'Show all';

/**
 * The HTML ID for the container to hold generated HTML.
 * @const
 * @type {string}
 */
press.twitterDirectory.CONTENT_CONTAINER = 'pc-twitter-directory';

/**
 * The text to use for navigation when no category is associated with a
 * directory item.
 * @const
 * @type {string}
 */
press.twitterDirectory.DEFAULT_CATEGORY = 'Company wide';

/**
 * The location of the icon to use for a directory item when none is provided
 * in the Spreadsheet.
 * @const
 * @type {string}
 */
press.twitterDirectory.DEFAULT_ICON = '/images/icons/favicon_colors-35.gif';

/**
 * The class name for a directory item.
 * @const
 * @type {string}
 */
press.twitterDirectory.DIR_ITEM = 'visible pc-directory-item';

/**
 * The class name for a secondary directory item (the "alternate" item).
 * @const
 * @type {string}
 */
press.twitterDirectory.DIR_ITEM_ALT = press.twitterDirectory.DIR_ITEM +
    ' pc-directory-item-alternate';

/**
 * The HTML ID for the container to hold generated for page navigation.
 * @const
 * @type {string}
 */
press.twitterDirectory.NAV_CONTAINER = 'pc-twitter-nav-container';

/**
 * The text string to link to additional information when no other text
 * is provided.
 * @const
 * @type {string}
 */
press.twitterDirectory.READ_MORE_TEXT = 'Read more on Twitter';

// Functions to update the display of HTML data on the page.
// These functions update the look of the page, not the data.
/**
 * Displays a specific category of information based on the navigation menu
 * selection.
 * @param {Object|string} selected The value of the navigation item that's
 *     chosen.
 */
press.twitterDirectory.displayCateg = function(selected) {
  press.twitterDirectory.hideCategs();

  var parent = selected.parentNode;

  // Checks if the "Show all" list item  is selected and every entry in the
  // directory should be shown instead of showing only one category. This is
  // used because there is no "all" category that contains every item.
  if (selected.firstChild.data === press.twitterDirectory.ALL_CATEGORIES) {
    press.twitterDirectory.showCategs();
    press.twitterDirectory.removeSelected();
    press.twitterDirectory.selectBackground(parent);
    selected.parentNode.className = 'pc-nav-selected';
    return;
  }

  var cat = selected.firstChild.data;

  // Page HTML will use '&' character, instead of '&amp;' element.
  cat = cat.replace(/&/g, '&amp;');

  for (var categ in press.categLookup) {
    // Allow type coercion: comparing object from category lookup to string
    // from page HTML.
    if (press.categLookup[categ] == cat) {
      // Do data look-ups with id-style category; not categorys written out
      // to the HTML page.
      cat = categ;
    }
  }

  press.twitterDirectory.removeSelected();
  press.twitterDirectory.selectBackground(parent);
  selected.parentNode.className = 'pc-nav-selected';

  for (var i = 0, id; id = press.navCategs[cat][i]; i++) {
    var twitAcct = document.getElementById(id);

    if (i % 2 === 0) {
      twitAcct.className = press.twitterDirectory.DIR_ITEM_ALT;
    } else {
      twitAcct.className = press.twitterDirectory.DIR_ITEM;
    }
  }
};

/**
 * Hides all directory items on the page.
 * This is called before showing a specific category in order to reset the page.
 */
press.twitterDirectory.hideCategs = function() {
  for (cat in press.navCategs) {
    for (var i = 0, id; id = press.navCategs[cat][i]; i++) {
      var twitAcct = document.getElementById(id);
      var cName = twitAcct.className;

      cName = cName.replace(/ pc-directory-item-alternate/, '');
      cName = cName.replace(/visible /, 'hidden ');
      twitAcct.className = cName;
    }
  }
};

/**
 * Updates the styles for the selected nav item.
 * @param {Object} parent An HTML element in the navigation list.
 */
press.twitterDirectory.selectBackground = function(parent) {
  while (parent.className !== 'pc-round-container-off') {
    parent = parent.parentNode;
  }

  parent.className = 'pc-round-container';
};

/**
 * Shows all directory items on the page (rather than a specific category).
 */
press.twitterDirectory.showCategs = function() {
  var directory =
      document.getElementById(press.twitterDirectory.CONTENT_CONTAINER);
  var allDivs = directory.getElementsByTagName('div');
  var divs = [];

  // Creats an array of all HTML DIV elements on the page that are contained
  // by the "dictory" DIV and that have an ID. This captures all of the
  // directory items. This is used when showing all of the directory
  // information on the page (rather than specific categories).
  for (var i = 0, div; div = allDivs[i]; i++) {
    if (div.id) {
      divs.push(div);
    }
  }

  for (var i = 0, div; div = divs[i]; i++) {
    if (i % 2 === 0) {
      div.className = press.twitterDirectory.DIR_ITEM_ALT;
    } else {
      div.className = press.twitterDirectory.DIR_ITEM;
    }
  }
};

/**
 * Removes the "selected" style from all navigation items.
 * This is called before asserting one navigation item as being in the
 * selected state.
 */
press.twitterDirectory.removeSelected = function() {
  var navContainer =
      document.getElementById(press.twitterDirectory.NAV_CONTAINER);
  var navItems = navContainer.getElementsByTagName('li');
  var divItems = navContainer.getElementsByTagName('div');

  // Remove "selected" styling from nav item text.
  for (var i = 0, navItem; navItem = navItems[i]; i++) {
    navItem.className = 'pc-nav';
  }

  // Remove "selected" styling for nav item background coloring.
  for (var j = 0, divItem; divItem = divItems[j]; j++) {
    if (divItem.className === 'pc-round-container') {
      divItem.className = 'pc-round-container-off';
    }
  }
};

// Methods used for the press site Twitter directory.
/**
 * Displays the directory and navigation.
 * This is called when the page is first loaded.
 * @param {Object} feedData The organized data from the Spreadsheet feed.
 */
press.twitterDirectory.init = function(feedData) {
  var twitDir = new press.twitterDirectory();
  var twitData = twitDir.organizeData(feedData);
  var navData = twitDir.organizeNav(twitData);

  twitDir.displayDir(twitData);
  twitDir.displayNav(navData);
};

// Methods used in the creation of the nav.
/**
 * Takes all of the data from the feed and associates each unique category
 * with each of the IDs that belong to that category. This is used to buld the
 * navigation.
 * @param {Object} twitData All of the data from the feed.
 * @return {Object} Associates each unique category from the feed data with
 *     all of the HTML ID names that are connected to the rest of the feed data.
 */
press.twitterDirectory.prototype.organizeNav = function(twitData) {
  var CAT = 0;
  var cats = {};

  press.categLookup = {};

  for (var id in twitData) {
    // Categories for accounts.
    var cat = press.cleanText_(twitData[id][CAT]);
    var displayCateg = cat;

    cat = press.textToId(cat.toString());

    if (!cats[cat]) {
      cats[cat] = [];
    }

    press.categLookup[cat] = displayCateg;
    cats[cat].push(id);
  }
  press.navCategs = cats;
  return cats;
};

/**
 * Displays an HTML navigation to show different categories of feed data.
 * @param {Object} navData Categorical data from the feed which associates each
 *     category with all HTML page ID elements that fall into that category.
 */
press.twitterDirectory.prototype.displayNav = function(navData) {
  var nav = document.getElementById(press.twitterDirectory.NAV_CONTAINER);
  var navHtml = '<ul><div class="pc-round-container">' + press.ROUND_TOP +
        '<li class="pc-nav-selected">' +
        '<a href="javascript:void(0)"' +
        'onClick="press.twitterDirectory.displayCateg(this)">' +
        press.twitterDirectory.ALL_CATEGORIES + '</a></li>' +
        press.ROUND_BOTTOM + '</div>';

  for (var twitCat in navData) {
    navHtml += '<div class="pc-round-container-off">' + press.ROUND_TOP +
        '<li><a href="javascript:void(0)"' +
        'onClick="press.twitterDirectory.displayCateg(this)">' +
        press.categLookup[twitCat] + '</a></li>' +
        press.ROUND_BOTTOM + '</div>';
  }

  navHtml += '</ul>';

  nav.innerHTML = navHtml;
};

// Methods used in the creation of the directory.
/**
 * Organizes all of the data from the feed into a format useful for the
 * directory and the directory's navigation.
 * @param {Object} feedData The organized data from the Spreadsheet feed.
 * @return {Object} Associates each directory item ID with all of the
 *     information for that item.
 */
press.twitterDirectory.prototype.organizeData = function(feedData) {
  var twitAccounts = {};

  for (var i = 0, row; row = feedData[i]; i++) {
    // Categorize each account.
    if (!row['category']) {
      row['category'] = press.twitterDirectory.DEFAULT_CATEGORY;
    }

    // Provide default image.
    if (!row['image']) {
      row['image'] = press.twitterDirectory.DEFAULT_ICON;
    }

    if (!row['linktext']) {
      row['linktext'] = press.twitterDirectory.READ_MORE_TEXT;
    }

    var twitId = press.textToId(row['category']) + '-' +
        press.textToId(row['rowTitle']);

    twitAccounts[twitId] = [row['category'], row['rowTitle'], row['url'],
        row['linktext'], row['image']];
  }
  return twitAccounts;
};

/**
 * Dislays the directory of items on the HTML page.
 * @param {Object} twitData All of the information from the feed that will
 *     be displayed on the page.
 */
press.twitterDirectory.prototype.displayDir = function(twitData) {
  var dir = document.getElementById(press.twitterDirectory.CONTENT_CONTAINER);
  var dirContent = '';
  var objCount = 0;
  var TWIT_TITLE = 1;
  var TWIT_URL = 2;
  var TWIT_TEXT = 3;
  var TWIT_IMG = 4;


  for (var twitId in twitData) {
    var divClass = press.twitterDirectory.DIR_ITEM;
    var imgSrc = twitData[twitId][TWIT_IMG];
    var imgClass = 'pc-directory-item-image';

    // Images of country flags are shorter.
    // Give them a different class so they display better.
    if (imgSrc.match('flags')) {
      imgClass = 'pc-directory-item-image-flag';
    }

    if (objCount % 2 === 0) {
      divClass = press.twitterDirectory.DIR_ITEM_ALT;
    }

    dirContent += '<div class="' + divClass + '" id="' + twitId +
        '"><a href="' + twitData[twitId][TWIT_URL] + '">' +
        '<div class="g-section g-tpl-50"><div class="g-unit g-first">' +
        '<img class="' + imgClass + '" src="' + imgSrc + '" />' +
        '</div><div class="g-unit">' +
        '<h3>' + twitData[twitId][TWIT_TITLE] + '</h3><p>' +
        twitData[twitId][TWIT_TEXT] + '</p></div></div></a></div>';
    objCount++;
  }

  dir.innerHTML = dirContent;
};

