<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="iGoogle Theme Manager BETA 2.8.3"
               description="Development version of the iGoogle Theme Manager. UNSTABLE - For internal testing only!"
               author_email="sterling.udell+gadgets@gmail.com"
               title_url="http://gad.getpla.net/theme_mgr/#tips" 
               author="Sterling Udell"
               author_location="North Wales, UK"
               author_affiliation="Udell Enterprises, Inc"
               author_photo="http://gad.getpla.net/images/my_photo.jpg"
               author_aboutme="Free-range programmer developing gadgets, map applications, and anything else that catches my interest."
               author_link="http://gad.getpla.net"
               author_quote="That's it... We'll go somewhere where there's cheese!"
               height="20"
               screenshot="http://gad.getpla.net/theme_mgr/theme_mgr_280.png"
               thumbnail="http://gad.getpla.net/theme_mgr/theme_mgr_120.png"
               singleton="true">

    <Require feature="setprefs" />
    <Require feature="analytics" />
    <Require feature="minimessage" />
  </ModulePrefs>

  <UserPref name="transparent" display_name="Transparent Controls" datatype="bool" default_value="true" />
  <UserPref name="themes" display_name="Add Theme URL" datatype="list" />
  <UserPref name="dev_mode" display_name="Developer Mode" datatype="bool" />
  <UserPref name="selected" datatype="hidden" />
  <UserPref name="not_cached" datatype="hidden" />
  <UserPref name="managed_change" datatype="hidden" default_value="0"/>
  <UserPref name="undo" datatype="hidden" />
  <UserPref name="first_run" datatype="hidden" default_value="1"/>

  <Content type="html-inline">
  <![CDATA[
    <style type="text/css">
      table {border-collapse: collapse}
      #main___MODULE_ID__ {display: none}
      .cached___MODULE_ID__ {text-align: center; width: 3.5em}
      .radio___MODULE_ID__ {width: 1.5em}
      .delbox___MODULE_ID__ {width: 1em; padding-right: 4px}
      #remove___MODULE_ID__ {text-align: right; padding-left: 1em; white-space: nowrap}
      #remove___MODULE_ID__ img {vertical-align: bottom; margin-right: 4px}
      #sponsor {text-align: right; margin-top: 0.5em; padding-right: 3px; padding-bottom: 0; padding-top: 0; font-size: 80%; border-left: none; border-bottom: none; border-right: none}
    </style>
    <p id="loading___MODULE_ID__">Loading...</p>
    <form><table id="main___MODULE_ID__"><tr>
        <th colspan="2">Theme</th>
        <th class="cached___MODULE_ID__" id="cached_hdr___MODULE_ID__" style="display: none">Cached</th>
      </tr><tr>
        <td><input type="radio" name="active" onclick="themeMgr.activate(-1)" id="none___MODULE_ID__" /></td>
        <td colspan="2">None</td>
      </tr><tr>
        <td colspan="2">Browse: <a href="http://inthemes.com/browse.php?clear=1&browse_cat=0&from_mgr=1"><em>in</em>Themes</a>, <a id="add___MODULE_ID__" href="/ig/directory?type=themes">iGoogle</a></td>
        <td colspan="2" id="remove___MODULE_ID__">Remove&nbsp;</td>
    </tr></table></form>
    <p id="sponsor">Sponsored by <a href="http://inthemes.com/?from_mgr=1"><em>in</em>Themes</a></p>
    <script type="text/javascript">
    if (window.themeMgr)
    {
      // Another instance of Theme Mgr found on the same page. Merge them.
      function merge__MODULE_ID__()
      {
        var otherMgr = window.themeMgr;
        otherMgr.pauseReload = true;

        // Hide this instance from the user 
        var thisMgr = _gel('m_' + '__MODULE_ID__');
        if (thisMgr)
          thisMgr.style.display = 'none';

        // Merge the theme URL arrays

        var combined = otherMgr.prefs.getArray('themes');
        var myPrefs = new _IG_Prefs(__MODULE_ID__);
        var myURLs = myPrefs.getArray('themes');

        var hash;
        var elements = [];
        for (var i = 0; i < myURLs.length; i++) 
          if (combined.indexOf(myURLs[i]) == -1)
          {
            combined.push(myURLs[i]);
            otherMgr.setPref('themes', combined);
            elements.push(otherMgr.addURL(myURLs[i]));
          }

        // Merge the "uncached" lists
        var myNoCache = myPrefs.getArray('not_cached');
        combined = otherMgr.prefs.getArray('not_cached');
        for (i = 0; i < myNoCache.length; i++)
          combined.push(myNoCache[i]);
        otherMgr.setPref('not_cached', combined);

        // Tell iGoogle not to show this instance again  
        _xsetp('m_' + '__MODULE_ID__' + '_enab=0');

        var index = otherMgr.pauseReload;
        otherMgr.pauseReload = false;
        if (otherMgr.reloadNeeded)
          // The other instance needs a reload anyway, so fire it off
          otherMgr.activate(index);
        else
          // No reload needed => Add any new themes to the other instance's display 
          for (i = 0; i < elements.length; i++) 
            otherMgr.displayRow(elements[i]);
      };
      merge__MODULE_ID__();
    }
    else
    {
      if (!Array.prototype.forEach)
      {
        Array.prototype.forEach = function (fun /*, thisp*/)
        {
          var len = this.length;
          if (typeof fun != "function")
            throw new TypeError();

          var thisp = arguments[1];
          for (var i = 0; i < len; i++)
          {
            if (i in this)
              fun.call(thisp, this[i], i, this);
          }
        };

        Array.prototype.indexOf = function (elt /*, from*/)
        {
          var len = this.length;
      
          var from = Number(arguments[1]) || 0;
          from = (from < 0)
               ? Math.ceil(from)
               : Math.floor(from);
          if (from < 0)
            from += len;
      
          for (; from < len; from++)
          {
            if (from in this &&
                this[from] === elt)
              return from;
          }
          return -1;
        };
      };

      String.prototype.jsHash = function ()
      {
        // with thanks to http://www.partow.net/programming/hashfunctions/index.html

        var hash = 1315423911;
    
        for (var i = 0; i < this.length; i++)
          hash ^= ((hash << 5) + this.charCodeAt(i) + (hash >> 2));

        return String(hash);
      };

      var themeMgr = {};

      themeMgr.prefs = new _IG_Prefs(__MODULE_ID__);
      themeMgr.msgr  = new _IG_MiniMessage(__MODULE_ID__);
      themeMgr.skins = [];
      themeMgr.main = _gel('main' + '_' + '__MODULE_ID__');
      themeMgr.devMode = themeMgr.prefs.getBool('dev_mode');
      themeMgr.searchColor = '';
      themeMgr.pauseReload  = false;
      themeMgr.reloadNeeded = false;

      themeMgr.arVersion = navigator.appVersion.split("MSIE");
      themeMgr.ieVersion = parseFloat(themeMgr.arVersion[1]);

      themeMgr.currentSkin = _theme_url;

      themeMgr.currentIndex = -1;

      themeMgr.getText = function (xmlNode)
      {
        // A cross-browser-compatible function to return the inner text of the given
        // XML node. For example, if the node was "<foo>bar</foo>", would return "bar".
        if (xmlNode.text)
          return xmlNode.text;
        if (xmlNode.data)
          return xmlNode.data;
        else if (xmlNode.innerText)
          return xmlNode.innerText;
        else if (xmlNode.textContent)
          return xmlNode.textContent;
        else if (xmlNode.firstChild)
          return themeMgr.getText(xmlNode.firstChild);
        else if (xmlNode.length > 0)
          return themeMgr.getText(xmlNode[0]);
        else
          return '';
      };

      themeMgr.addEventHandler = function (element, event, func, phase)
      {
        /* A generic, cross-browser technique for adding an event handler to a DOM element
           without disturbing any other handlers that have been tied to it, by any means.
           
           Parms:
           
            element - the DOM element to attach to. Either the node itself (including "window") or a 
                      string containing the ID of the element.
                      
            event - the event name as a string, either as "load", "onload", or "onLoad" (case-insensitive)
            
            func - the function to assign to the event. Can be a closure.
            
            phase - string, 'capturing' or 'bubbling'. Optional, defaults to 'capturing'. Not
                    applicable to IE<7 and some older browsers.
                    
           Examples:
            addEventHandler(window, 'load', init);
            addEventHandler(window, 'unload', GUnload);
            addEventHandler(listName, 'onClick', function() {renamePoint(id, 'list')});
        */
        
        // Normalize parms
      
        if ((typeof element) == 'string')
          element = document.getElementById(element);
        if (!element ||
            (element == undefined))
          return;
      
        event = event.toLowerCase();
        if (event.substr(0, 2) == 'on')
        {
          var longEvent  = event;
          var shortEvent = event.substr(2);
        }
        else
        {
          var longEvent  = 'on' + event;
          var shortEvent = event;
        }
      
        var useCapture = (phase == 'bubbling');
        
        // Attach the event
        
        if ((shortEvent != 'click') &&
            element.addEventListener)
          // W3C DOM Level 2 compliant
          element.addEventListener(shortEvent, func, useCapture);
          
        else if ((shortEvent != 'click') &&
                 element.attachEvent)
          // Most versions of IE
          element.attachEvent(longEvent, func);
          
        else
        {
          // Older browsers
          //  - Note that the handler does not get an event object parm - not sure if this is an issue
          //    with the browser versions that will see this code block or not.
          var oldHandler = element[longEvent];
      
          if (typeof(oldHandler) == 'function') 
          {
            element[longEvent] = function(e) 
              {
                var result = oldHandler(e);
                return (func(e) && result);
              };
          }
          else 
            element[longEvent] = func;
        }
      };
      
      themeMgr.prefQueue = {themes: null, 
                            selected: null, 
                            not_cached: null, 
                            managed_change: null, 
                            undo: null};
      themeMgr.setPref = function (name, value)
      {
        /*
          My own preference-setting wrapper, which both fires off an API prefs.set request
          and adds the values to an internal queue that gets wrapped into the activate method's
          _setp call. This causes the prefs to get saved even if the activate happens before
          prefs.set's XHR completes.
          
          NOTE: Don't forget to add preferences you want saved via this method to the prefQueue above!
        */

        if ((typeof value.join) == 'function')
        {
          themeMgr.prefs.setArray(name, value);
          value = value.join('|');
        }
        else
          themeMgr.prefs.set(name, value);

        if (value != themeMgr.prefQueue[name])
        {
          themeMgr.prefQueue[name] = value;
          setTimeout('themeMgr.prefQueue.' + name + ' = null', 30000);
        }
      };

      themeMgr.isCached = function (index) 
      {
        var checkbox = _gel('cache_' + index + '_' + '__MODULE_ID__');
        if (checkbox)
          return checkbox.checked;
        else
          try
          {
            var uncachedURLs = themeMgr.prefs.getString('not_cached');
            return (uncachedURLs.indexOf(themeMgr.skins[index].hash) == -1);
          }
          catch (e)
          {
            return true;  // default
          }
      };

      themeMgr.getPrefQueue = function ()
      {
        var parms = [];

        for (var name in themeMgr.prefQueue)
          if (themeMgr.prefQueue[name] !== null)
            parms.push('m_' + __MODULE_ID__ + '_up_' + name + '=' + encodeURIComponent(themeMgr.prefQueue[name]));

        return parms;
      };

      themeMgr.saveLocations = function ()
      {
        var locPref = '';
        for (var hash in themeMgr.locations)
          if (hash)
            locPref = locPref + hash + '=' + themeMgr.locations[hash] + '|';
        locPref = locPref.replace('|$', '');

        themeMgr.setPref('locations', locPref);
      };

      themeMgr.saveCache = function (index)
      {
        var checkbox = _gel('cache_' + index + '_' + '__MODULE_ID__');
        if (!checkbox)
          return;

        var uncachedURLs = themeMgr.prefs.getString('not_cached').split('|');
        var inPref = uncachedURLs.indexOf(themeMgr.skins[index].hash);
        if (checkbox.checked)
        {
          if (inPref > -1)
            uncachedURLs.splice(inPref, 1);
        }
        else 
        {
          if (inPref == -1)
            uncachedURLs.push(themeMgr.skins[index].hash);
        }

        themeMgr.setPref('not_cached', uncachedURLs.join('|'));

        if (index == themeMgr.currentIndex)
          themeMgr.activate(index, {force: true});
      };

      themeMgr.getURLSkin = function () 
      {
        var urlSkin = _args();         //
        urlSkin = urlSkin['skin'];     // needs to remain on 2 lines or the packed code doesn't work?

        if (urlSkin == undefined)
          urlSkin = '';

        return urlSkin;
      };

      themeMgr.activate = function (index, options)
      {
themeMgr.debugMsg('Activate called: ' + index);
        options = options || {};
        var requested = '';
        var useDir = true;
        if (index > -1)
        {
          requested = themeMgr.skins[index].url;
          useDir = themeMgr.skins[index].legacyXML ||
                   (themeMgr.skins[index].isListed && 
                    themeMgr.isCached(index));
        }

        if (requested != themeMgr.prefs.getString('selected'))
          themeMgr.setPref('selected', requested);

        if (themeMgr.pauseReload)
        {
          themeMgr.pauseReload = index;
          return;
        }

        if ((index == themeMgr.currentIndex) &&
            !options.force)
          return;

        var url = decodeURI(document.location);
        url = url.replace(/\?nocache=[0-9]+/, '');
        url = url.replace('#', '');
        url = url.replace(/skin=[^&]*&?/, '');
        url = url.replace(/override_selection=1[^&]*&?/, '');
        url = url.replace(/[\?|&]$/, '');

        themeMgr.prefQueue['managed_change'] = 1;
        var parms = themeMgr.getPrefQueue();
        if (useDir)
        {
          requested = requested.replace('http://www.google.com/ig/', '');
          parms.push('skin' + '=' + encodeURIComponent(requested));
          
          if (themeMgr.isCached(index))
            parms.push('skin_cached' + '=' + '1');
          else
            parms.push('skin_cached' + '=' + '0');
        }
        else
        {
          parms.push('skin' + '=');
          if (requested.indexOf('://') == -1)
            requested = 'http://www.google.com/ig/' + requested;

if (requested.indexOf('live_planet_n.xml') > -1)
  requested = requested.replace('www.', '');

          if (!themeMgr.isCached(index) &&
              themeMgr.devMode)
            requested = requested + '?' + 'nocache=' + Number(new Date());

          requested = encodeURIComponent(requested);

          if (url.indexOf('?') > -1)
            url = url + '&' + 'skin' + '=' + requested;
          else
            url = url + '?' + 'skin' + '=' + requested;
        }

themeMgr.debugMsg('Activating: ' + requested);
        _dlsetp(parms.join('&'), _esc(url));
      };

      themeMgr.updateTitle = function (index)
      {
        // Update the displayed title for the given theme

        var row = _gel('row_' + index + '_' + '__MODULE_ID__');
        if (!row)
          return;
        var cells = row.getElementsByTagName('td');

        cells[1].style.color = '';
        if (themeMgr.skins[index].title)
        {
          var href = '';
          if (themeMgr.devMode)
          {
            href = themeMgr.skins[index].url;
            if (href.indexOf('://') == -1)
              href = 'http://www.google.com/ig/' + href;
          }
          else if (themeMgr.skins[index].isListed)
            href = 'http://www.google.com/ig/directory?type=themes&url=' + 
                   themeMgr.skins[index].url.replace('http://www.google.com/ig/', ''); 

          var title = themeMgr.skins[index].title;
          if (href == '')
            cells[1].innerHTML = title;
          else
            cells[1].innerHTML = '<a target="xml" href="' + href + '">' + title + '</a>';
        }

        var checkbox = _gel('cache_' + index + '_' + '__MODULE_ID__');
        if (checkbox)
          checkbox.disabled = (themeMgr.skins[index].legacyXML ||
                               (!themeMgr.skins[index].isListed && !themeMgr.devMode));
      };

      themeMgr.receiveListing = function (response, index) 
      {
        if ((response != '') &&
            (response.indexOf('id="no_details"') == -1))
        {
          // XML found in Google directory
          themeMgr.skins[index].isListed = true;
          if ((themeMgr.skins[index].url == themeMgr.prefs.getString('selected')) &&
              (themeMgr.isCached(index) != (themeMgr.getURLSkin() == '')))
          {
            themeMgr.activate(index, {force: true});
            return;
          }
        }
        else
        {
          // XML not found in Google dir
          themeMgr.skins[index].legacyXML = false;
          if ((themeMgr.skins[index].url == themeMgr.prefs.getString('selected')) &&
              (themeMgr.getURLSkin() == ''))
          {
            themeMgr.activate(index, {force: true});
            return;
          }
          var checkbox = _gel('cache_' + index + '_' + '__MODULE_ID__');
          if (checkbox)
            checkbox.disabled = !themeMgr.devMode;
        }

        if ((themeMgr.skins[index].url == themeMgr.prefs.getString('selected')) &&
            (index != themeMgr.currentIndex))
        {
          themeMgr.activate(index);
        }
        else
          themeMgr.updateTitle(index);
      };

      themeMgr.displayRow = function (element) 
      {
        // Add the supplied element (from the internal skins array) to the on-screen display

try {
          var index = themeMgr.main.rows.length - 3;
} catch (e) {
  // IE8 beta 1 compatibility - try with a later release
  var index = themeMgr.main.firstChild.childNodes.length - 3;
}

        var newRow = themeMgr.main.insertRow(index + 2);
        newRow.id = 'row_' + index + '_' + '__MODULE_ID__';

        var newCell = newRow.insertCell(-1);
        newCell.className = 'radio_' + '__MODULE_ID__';
        var newHTML = '<input type="radio" name="active" onclick="themeMgr.activate(' + index + ')"';
        if (index == themeMgr.currentIndex)
          newHTML += ' checked="checked"';
        newHTML += ' />';
        newCell.innerHTML = newHTML;

        newCell = newRow.insertCell(-1);
        if (themeMgr.devMode)
        {
          var href = element.url;
          if (href.indexOf('://') == -1)
            href = 'http://www.google.com/ig/' + href;
          newCell.innerHTML = '<a target="xml" href="' + href + '">' + element.url.replace(/^.+\//, '') + '</a>';
        }
        else
          newCell.innerHTML = element.url.replace(/^.+\//, '');
        newCell.style.color = 'gray';

        newCell = newRow.insertCell(-1);
        newHTML = '<input type="checkbox" id="cache_' + index + '_' + '__MODULE_ID__' + '" onclick="themeMgr.saveCache(' + index + ', this)"';
        if (element.legacyXML || (element.isListed && !themeMgr.devMode))
          newHTML += ' disabled="disabled"';
        newHTML += ' />';
        newCell.innerHTML = newHTML;
        newCell.className = 'cached_' + '__MODULE_ID__';

        newCell = newRow.insertCell(-1);
        newHTML = '<a onclick="themeMgr.remove(' + index + '); return false" href="#" class="delbox" title="Remove this theme" />';
        newCell.innerHTML = newHTML;
        newCell.className = 'delbox_' + '__MODULE_ID__';
  
        var url = element.url;
        if (url.indexOf('://') == -1)
          url = 'http://www.google.com/ig/' + url;
          
        if (themeMgr.devMode)
          var opts = {refreshInterval: 0};
        else
          var opts = {};

        _IG_FetchXmlContent(
          url, 
          function (response) {themeMgr.receiveTheme(response, element.hash)}, opts);
      };

      themeMgr.doneLoading = function ()
      {
        // Replace the "Loading..." message with the main content table
        _gel('loading' + '_' + '__MODULE_ID__').style.display = 'none';
        themeMgr.main.style.display = 'block';
      };

      themeMgr.display = function ()
      {
        var newCacheList = '';
        var locData;

        if (themeMgr.skins.length == 0)
        {
          _gel('remove' + '_' + '__MODULE_ID__').style.display = 'none';
          themeMgr.doneLoading();
        }
        else
        {
          var uncachedURLs = themeMgr.prefs.getString('not_cached').split('|');
          var checkbox;
          themeMgr.skins.forEach(function (element, index)
          {
            themeMgr.displayRow(element);
            if ((uncachedURLs.indexOf(element.hash) != -1)
|| ((themeMgr.prefs.getString('first_run') == '1') && (element.url.indexOf('live_planet_n.xml') > -1)))
              newCacheList = newCacheList + '|' + element.hash;
            else
            {
              checkbox = _gel('cache_' + index + '_' + '__MODULE_ID__');
              if (checkbox)
                checkbox.checked = true;
            }
          });

          themeMgr.setPref('not_cached', newCacheList);
themeMgr.setPref('first_run', '0');

          // If the themes on the list fail to load, this prevents the display from getting stuck on "Loading..."
          setTimeout('themeMgr.doneLoading()', 5000);
        }
      };

      themeMgr.getAppliedStyle = function (element, style) 
      {
        if (element)
          if (document.defaultView && 
              document.defaultView.getComputedStyle)
            return document.defaultView.getComputedStyle(element, '').getPropertyValue(style);
          else if (element.currentStyle)
          {
            var hyphen = style.indexOf('-');
            if (hyphen > -1)
              // Convert hyphenated notation to sad camel case
              style = style.substr(0, hyphen) + style.substr(hyphen + 1, 1).toUpperCase() + style.substr(hyphen + 2);

            return element.currentStyle[style];
          }

        return  '';
      };

      themeMgr.makeTransparent = function () 
      {
        var header = _gel('nhdrwrap');
        if (header)
          var links = header.getElementsByTagName('a');

        if (links.length > 0)
          themeMgr.searchColor = themeMgr.getAppliedStyle(links[0], 'color');

        if (themeMgr.searchColor != '')
        {
          var controls = [_gel('q'), _gel('btnG'), _gel('btnI')];

          for (var i = 0; i < controls.length; i++)
            if (controls[i])
            {
              controls[i].style.backgroundColor = 'transparent';
              controls[i].style.color           = themeMgr.searchColor;
              if (i > 0)
                controls[i].style.fontWeight    = 'bold';
            }

          if (controls[0])
          {
            themeMgr.addEventHandler(controls[0], 'keydown', function () {themeMgr.showSearch(true)});
            themeMgr.addEventHandler(controls[0], 'click',   function () {themeMgr.showSearch(true)});
            themeMgr.addEventHandler(controls[0], 'blur',    function ()
            {
              themeMgr.showSearch(false);
              themeMgr.addEventHandler(controls[0], 'focus', function () {themeMgr.showSearch(true)});
            });
            
          }

          controls = _gelstn('li');
          var classes;
          for (i = 0; i < controls.length; i++)
          {
            classes = controls[i].className.split(' ');
            if (classes.indexOf('tab') > -1)
              if (classes.indexOf('selectedtab') > -1)
              {
                controls[i].style.opacity = '0.75';
                controls[i].style.filter  = 'alpha(opacity=75)';
              }
              else if (classes.indexOf('unselectedtab') > -1)
              {
                controls[i].style.opacity = '0.5';
                controls[i].style.filter  = 'alpha(opacity=50)';
//                controls[i].style.backgroundColor = 'transparent';
//                controls[i].style.color           = themeMgr.searchColor;
                controls[i].style.fontWeight      = 'bold';
              }
          }
        }
      };

      themeMgr.showSearch = function (opaque) 
      {
        if (themeMgr.searchColor != '')
        {
          var control = _gel('q');
          if (control)
            if (opaque)
            {
              control.style.backgroundColor = 'white';
              control.style.color           = 'black';
            }
            else
            {
              control.style.backgroundColor = 'transparent';
              control.style.color           = themeMgr.searchColor;
            }
        }
      };

      themeMgr.receiveTheme = function (response, hash) 
      {
        if ((response == null) ||
            (typeof (response) != 'object'))
          return;

        for (var index = 0; index < themeMgr.skins.length; index++) 
          if (themeMgr.skins[index].hash == hash)
            break;
        if (index >= themeMgr.skins.length)
          return;

        var row = _gel('row_' + index + '_' + '__MODULE_ID__');
        var cells = row.getElementsByTagName('td');

        if (response.firstChild == null)
        {
          cells[1].innerHTML += ': <i>Invalid XML</i>';
          return;
        }

        var meta = response.getElementsByTagName('Meta');
        if (meta.length)
        {
          // API-style XML

          for (var n = 0; n < meta.length; n++)
            if (meta[n].getAttribute('name') == 'title')
            {
              themeMgr.skins[index].title     = themeMgr.getText(meta[n]);
              themeMgr.skins[index].legacyXML = false;
              break;
            }

          if (index == themeMgr.currentIndex)
            themeMgr.addEventHandler(window, 'load', function () {setTimeout('themeMgr.fixIcons()', 2000)});
        }
        else
        {
          // Legacy XML (pre-API)

          var titleTags = response.getElementsByTagName('title');
          if (titleTags.length)
          {
            themeMgr.skins[index].title     = themeMgr.getText(titleTags[0]);
            themeMgr.skins[index].legacyXML = true;
          }
        }
if (themeMgr.skins[index].url.indexOf('live_planet_n.xml') > -1)
  themeMgr.skins[index].title = 'DaylightMap - Northern Hemisphere';
else if (themeMgr.skins[index].url.indexOf('live_planet_s.xml') > -1)
  themeMgr.skins[index].title = 'DaylightMap - Southern Hemisphere';

        themeMgr.updateTitle(index);
        themeMgr.doneLoading();
      };

      themeMgr.remove = function (index)
      {
        var title = themeMgr.skins[index].title;
        if (!title)
          title = themeMgr.skins[index].url;

        if (confirm('Remove "' + title + '" theme from page?'))
        {
          var urls = themeMgr.prefs.getArray('themes');
          for (var n = 0; n < urls.length; n++) 
            if (urls[n] == themeMgr.skins[index].url)
            {
              urls.splice(n, 1);
              themeMgr.setPref('themes', urls);

              if (index == themeMgr.currentIndex)
                setTimeout('themeMgr.activate(-1)', 2000);
              else
              {
                _gel('row_' + index + '_' + '__MODULE_ID__').style.display = 'none';

                if (urls.length == 0)
                {
                  _gel('cached_hdr_' + '__MODULE_ID__').style.display = 'none';
                  _gel('remove' + '_' + '__MODULE_ID__').style.display = 'none';
                }
              }
              
              break;
            }
        }
      };

      themeMgr.addURL = function (newURL) 
      {
        // Add the supplied theme URL to the internal skins array

        var element = {url: newURL, isListed: false, hash: newURL.jsHash()};

        if ((newURL.indexOf('://') == -1) ||
            (newURL.indexOf('www.google.com/ig/') > -1))
          element.legacyXML = true;
        else
          element.legacyXML = false;

        themeMgr.skins.push(element);
        
        return element;
      };
      
      themeMgr.debugMsg = function (msg)
      {
        if (window.console)
          console.log(msg);
      };
      
      themeMgr.fixIcons = function ()
      {
        // Work around iGoogle hole where certain icons can be invisibly white-on-white

        var headerColor = themeMgr.getAppliedStyle(_gel('m_' + '__MODULE_ID__' + '_h').parentNode, 'background-color');

        // Feedreader expand icons 
        var links = _gelstn('a');
        for (var n = 0; n < links.length; n++)
          if ((links[n].className.indexOf('fmaxbox') > -1) &&
              (themeMgr.getAppliedStyle(links[n], 'background-image').indexOf('/ffffff_expand.gif') > -1))
          {
            links[n].style.position = 'relative';
            links[n].style.zIndex = '2';

            links[n].parentNode.style.position = 'relative';
            links[n].parentNode.style.zIndex = '0';
            links[n].parentNode.style.paddingLeft = '3px';

            newDiv = document.createElement('div');
            links[n].parentNode.appendChild(newDiv);
            newDiv.style.backgroundColor = headerColor;
            newDiv.style.position = 'absolute';
            newDiv.style.width = '18px';
            newDiv.style.height = '18px';
            newDiv.style.top = '3px';
            newDiv.style.left = '0px';
            newDiv.style.zIndex = '1';
          }

        // My own "remove a theme" icons
        links = _gelstn('td');
        for (var n = 0; n < links.length; n++)
          if (links[n].className.indexOf('delbox_' + '__MODULE_ID__') > -1)
            links[n].style.backgroundColor = headerColor;
      };

      themeMgr.untinify = function (tiny, urls) 
      {
        _IG_FetchContent('http://gad.getpla.net/theme_mgr/tinyurl.php?tiny=' + tiny,
        function (response)
        {
          var urls = themeMgr.prefs.getArray('themes');
          var index = urls.indexOf(tiny);
          urls.splice(index, 1, response);
          themeMgr.setPref('themes', urls);
          themeMgr.setPref('selected', response);
          themeMgr.init();
        });
      };

      themeMgr.init = function () 
      {
        var urls = themeMgr.prefs.getArray('themes');
        if (urls.length)
        {
          for (var i = 0; i < urls.length; i++)
            if ((urls[i].length <= 8) &&
                (urls[i].search(/[\/\.]/) == -1))
            {
              themeMgr.untinify(urls.splice(i, 1)[0]);
              return;
            }
        }

        var delLink = _gel('remove' + '_' + '__MODULE_ID__');
        if (delLink)
          delLink.appendChild(_IG_GetImage('http://gad.getpla.net/theme_mgr/up_arrow.png'));

        themeMgr.reloadNeeded = false;
        themeMgr.currentSkin = themeMgr.currentSkin.replace(/\?.+/, '');

if (themeMgr.currentSkin.indexOf('live_planet_n.xml') > -1)
  if (themeMgr.currentSkin.indexOf('www.') == -1)
    themeMgr.currentSkin = themeMgr.currentSkin.replace('daylightmap.com', 'www.daylightmap.com');

themeMgr.debugMsg('Init: currentSkin = ' + themeMgr.currentSkin);

        var urlSkin = themeMgr.getURLSkin();
        var lastCache = -1;
        var currentIsListed = false;
        if (urlSkin != '')
        {
          if (urlSkin.indexOf('nocache') > 0)
            lastCache = parseInt(decodeURIComponent(urlSkin).replace(/.+nocache=/, '').replace(/\?$/, ''));
        }
        else
        {
          if (themeMgr.currentSkin != '')
            currentIsListed = true;
        }

        var undo = _gel('undo' + '_msg');
        if (undo)
        {
          if (themeMgr.prefs.getBool('managed_change'))
          {
            // Suppress Google's "Your theme has been changed" message
            undo.style.display = 'none';
            _xsetp('clrundo=');
            undo = false;
            themeMgr.setPref('undo', '');
          }
          else
            themeMgr.setPref('undo', themeMgr.prefs.getString('selected'));
        }

themeMgr.debugMsg('Init: prefs.selected = ' + themeMgr.prefs.getString('selected'));

        if (undo ||
            themeMgr.prefs.getBool('managed_change') ||
            (_args()['override_selection'] == 1))
          // The user has manually selected a new theme
          var selectedSkin = themeMgr.currentSkin;
        else
          var selectedSkin = themeMgr.prefs.getString('selected');

themeMgr.debugMsg('Init: selectedSkin = ' + selectedSkin);

        // Load the URL list from preferences into the master array
        var selectedIndex = -1;
        for (i = 0; i < urls.length; i++)
        {
          themeMgr.addURL(urls[i]);

          if ((themeMgr.currentSkin != '') &&
              (urls[i].indexOf(themeMgr.currentSkin) > -1))
          {
            // This is the theme that iGoogle is using
            themeMgr.currentIndex = i;
            if (currentIsListed)
              themeMgr.skins[i].isListed = true;
          }

          if (urls[i] == selectedSkin)
            // This is the theme that the user has previously chosen
            selectedIndex = i;
        }

        // Check if a reload is needed - there are a number of cases

        // "Incorrect cache state" case
        if (selectedIndex == themeMgr.currentIndex)
        {
          themeMgr.setPref('selected', themeMgr.currentSkin);

          // We only care about the cache state if the current theme is selected
          if (themeMgr.devMode)
          {
            // Developer mode - basic rule is whether the "nocache" url parm is too old
            if (!themeMgr.isCached(selectedIndex) &&
                ((lastCache == -1) ||
                 isNaN(lastCache) ||
                 (Number(new Date()) - lastCache > 15000)))
              themeMgr.reloadNeeded = true;
          }
else if ((urlSkin.indexOf('live_planet_n.xml') > -1) &&
    (urlSkin.indexOf('www.') > -1))
  themeMgr.reloadNeeded = true;
          else
            themeMgr.reloadNeeded = false;
        }

        // "Incomplete IE page load" case
        if (themeMgr.ieVersion < 7)
        {
          var modules = _gel('modules');
          var padding = modules.currentStyle.paddingTop;
          padding = parseInt(padding.replace(/px$/, ''));
          if (padding == 0)
            window.location.reload(true);
        }

        if (themeMgr.currentIndex == -1)
        {
          if ((themeMgr.currentSkin == '') ||
              (themeMgr.currentSkin == undefined))
            _gel('none_' + '__MODULE_ID__').checked = true;

          else if ((themeMgr.skins.length == 0) || 
                   (urlSkin != '') ||
                   undo)
          {
            // A new theme has been added, so add it to our own lists too

            themeMgr.skins.push({url: themeMgr.currentSkin, isListed: false, legacyXML: true, hash: themeMgr.currentSkin.jsHash()});
            themeMgr.currentIndex = themeMgr.skins.length - 1;

            urls.push(themeMgr.currentSkin);
            themeMgr.setPref('themes', urls);
          }
        }

        // The following preferences need to be initialized
        themeMgr.setPref('managed_change', '0');

        if (themeMgr.reloadNeeded)
          themeMgr.activate(selectedIndex , {force: true});
        else
        {
          themeMgr.display();
          if (themeMgr.skins.length)
            _gel('cached_hdr_' + '__MODULE_ID__').style.display = '';
  
          themeMgr.skins.forEach(function (element, index)
          {
            _IG_FetchContent(
              'http://www.google.com/ig/directory?type=themes&url=' + element.url.replace('http://www.google.com/ig/', ''), 
              function(response) {themeMgr.receiveListing(response, index)});
          });

          if (undo)
          {
            // Google's Undo functionality needs a little help to work with Theme Mgr
            var links = undo.getElementsByTagName('a');
            if (links.length)
              links[0].onclick = function ()
              {
                var index = urls.indexOf(themeMgr.prefs.getString('undo'));
                if (index > -1)
                  themeMgr.activate(index);
                else
                {
                  // really shouldn't happen if our own undo functionality is working right
                  themeMgr.prefQueue['managed_change'] = 1;
                  var parms = themeMgr.getPrefQueue();
                  _dlsetp('undo' + '&' + parms.join('&'));
                }
                return false;
              };
          }

          if ((themeMgr.currentIndex > -1) &&
              (themeMgr.prefs.getBool('transparent')))
            // Make the search controls transparent
            themeMgr.addEventHandler(window, 'load', themeMgr.makeTransparent);
  
          // Track this gadget using Google Analytics.
          _IG_Analytics("UA-1556555-7", "/theme_manager");
        }
      };
      themeMgr.init();
    }
    </script>
  ]]>
  </Content>
</Module> 
