// this file requires tiobe.js and siteStructure.js
//
//
////////////////////////////////////////////////////////////////////////

//
var loadedDivs;
var clearedDivs;

// Jump out of frame
if( parent.frames.length > 0 ) {
  parent.location.href = location.href;
}

// Call loadSitePageRoot when the base-page has finished loading
addEventHandler( window, 'load', function() {
  var qmKey;

  // Some pages are too large or unimportant to client-side include.
  // Check if a page does not use client-side include by checking
  // for the two DIVs that always exist in normal pages and probably
  // not in non-included pages.
  if( window.pageName ||
      !document.getElementById( 'maincontent' ) ||
      !document.getElementById( 'subcontent') ) {
    qmKey = window.pageName ? window.pageName : '';
    createCrumbs();

    showSubcontent( hasSubcontent() );
  } else {
    loadedDivs = Array();
    clearedDivs = Array();

    if( window['urlPageName'] ) {
      qmKey = urlPageName;
    } else {
      // get key from url, as ....?key[&...]
      var qmLoc = location.href.indexOf('?');
          qmKey = (qmLoc < 0 ? (urlPageName?urlPageName:'') : location.href.substring( qmLoc+1 ) );

      if( qmKey ) location.href = 'index.php/' + qmKey;
    }

    //// fix url for testing on localhost
    if( /:8080\//.test( location.href ) ) {
      if( /^www.tiobe.com.*/.test(qmKey) ) {
        var wtc = qmKey.lastIndexOf( 'www.tiobe.com' );
        qmKey = qmKey.substring( wtc + 13 );
      }
      if( /^\/?index.php$/.test(qmKey) ) {
        qmKey = 'home';
      }
    }
    ////

    var qmAmp = qmKey.indexOf('&');
    if( qmAmp >= 0 ) qmKey = qmKey.substring(0,qmAmp);
    var qmHash = qmKey.indexOf('#');
    if( qmHash >= 0 ) qmKey = qmKey.substring(0,qmHash);

    // all included pages required location.href not to end in .html
    var end = location.href.substring( location.href.lastIndexOf('/')+1 );
    if( qmKey == '' && (end.contains('index.html') || end.endsWith('www.tiobe.com') || end == '') ) {
      qmKey = 'home';
    }
    window.pageName = qmKey;

    loadSitePageRoot( qmKey );
  }
  createMenu( qmKey );
});

/////////////////////////////////////////////////////////////////////////////

// Log the given link at Google analytics.
// Example of use:
//  <a href="someLink.html" onClick="logClick(this);">
//
// [urlOrElement]  url to add to log, or node (when called with 'this')
//                 which can contain a src or href attribute to add to
//                 log. If omitted the location of the current page will
//                 be used.
// returns true.
function logLink(urlOrNode) {
  var url;
  if( !urlOrNode ) urlOrNode = location.href;

  if( typeof urlOrNode == 'string' ) {
    url = urlOrNode;
  } else {
    var node = urlOrNode;
    if( node.href ) url = node.href;
    if( node.src ) url = node.src;
  }
  if( url && window._uacct ) {
    // perform the actual logging
    if( window.urchinTracker ) {
      urchinTracker( url );
    }
    //alert('log: '+url);
  }
  return true;
}

// Relocate to a different page.
//
// name   Name of a key in the site structure, or a url to a page that
//        should be showed outside the web site.
//
function relocate(name) {
  // if name contains ':' or two or more slashes, it is
  // assumed to be a location outside the main web site.
  if( name.indexOf(':') > 0 || name.indexOf('/') != name.lastIndexOf('/') ) {
    location.href = (name.indexOf(':')<0?urlBase:'') + name;
  } else {
    loadSitePageRoot( name );
  }
}


// Find value of key in the 'pages' array of siteStructure and call loadSitePage for it.
function loadSitePageRoot(key) {
  var pageInfo;

  // find key in any of the 'pages' arrays
  findLoop:
  for(var pagesName in siteStructure) {
    var pagesInfo = siteStructure[pagesName];
    if( pagesName == key ) {
      if( pagesInfo['relocate'] ) {
        relocate( pagesInfo['relocate'] );
        return;
      }
      if( !pagesInfo['pages'] ) {
        loadSitePage( pagesInfo );
        return;
      }
    }
    var pages = pagesInfo['pages'];
    if( pages ) {
      for(var pageName in pages) {
        if( key == pagesName || key == pageName ) {
          pageInfo = pages[ pageName ];
          break findLoop;
        }
      }
    }
  }

  if( !pageInfo ) {
    pageInfo = {
      'maincontent' : key
    };
    pagesInfo = null;
    pagesName = null;
    pageName = null;
  }

  // Load the found page
  if( pageInfo ) {
    loadSitePage( pageInfo );
    createCrumbs( pagesInfo, pagesName, pageInfo, pageName );
  } else {
    if( key != '' ) {
      alert( 'Unknown page identifier provided: ' + key );
      location.href = '/index.php/home';
      return;
    }
    if( !hasSubcontent() ) {
      showSubcontent( false );
    }
  }
}

// Load divs from siteStructure array (tiobe.js should be loaded already)
function loadSitePage(pageInfo) {
  if( !pageInfo ) alert('loadSitePage: empty pageInfo supplied!');
  var fullwidth;
  var emptyMargin;

  // Handle each variable in pageInfo (label, title, divIds, etc)
  for(var name in pageInfo) {
    var value = pageInfo[ name ];
    var lcname = name.toLowerCase();

    if( lcname == 'isdefault' ) {
      // not used here
    } else

    if( lcname == 'relocate' ) {
      relocate( value );
    } else

    if( lcname == 'nomenu' ) {
      // not used here -- to hide these pages from the menu
    } else

    if( lcname == 'nositemap' ) {
      // not used here -- to hide these pages from the site map
    } else

    if( lcname == 'label' ) {
      if( !pageInfo[ 'title' ] ) {
        document.title = 'TIOBE Software: ' + value;
      }
    } else

    if( lcname == 'title' ) {
      document.title = 'TIOBE Software: ' + value;

    } else
    if( lcname == 'emptymargin' ) {
      if( value ) {
        emptyMargin = true;
      }
    } else
    if( lcname == 'fullwidth' ) {
      if( value ) {
        fullwidth = true;
        // side effect: clear subcontent divs
        document.getElementById( 'subcontent1' ).innerHTML = '';
        document.getElementById( 'subcontent2' ).innerHTML = '';
        clearedDivs['subcontent1'] = true; // prevent loading
        clearedDivs['subcontent2'] = true; // prevent loading
      }

    } else {
      // <name> is name of div to load <url> into
      var urls;

      if( typeof value == 'string' ) {
        urls = [ value ];
      } else {
        urls = value;
      }
      var div = document.getElementById( name );
      if( div ) {
        if( !urls || urls[0] == '' ) {
          div.innerHTML = ' ';
          clearedDivs[name] = true;
        } else

        if( !clearedDivs[name] && !loadedDivs[name] ) { // innerHTML might be loading asynchronously
          loadedDivs[name] = true;

          var onLoadedData = function(target, newUrl, data) {
            // Set the loaded data in the target div.
            setHtml( target, data );
          };

          // called when a url failed to load
          var onLoadError = function(target, url, errorId, errotText) {
            target.innerHTML = 'load error';
          };

          // Check url and log link (if main content)
          for(var urlIndex in urls) {
            var url = urls[ urlIndex];

            if( url == 'sitemap'  ) {
              setHtml( div, getSitemap(), urlIndex>0 );
              if( urls.length == 1 ) urls = [];

            } else {
              if( url.indexOf('content') < 0 ) {
                urls[ urlIndex] = 'content/' + url;
              }

              // Log to google analytics, only for main content
              if( name == 'maincontent' ) {
                logLink( url );
              }
            }
          }

          // Asynchronously load the page into div
          if( urls.length > 0 ) {
            loadContent( div, urls, onLoadedData );
          }
        }
      } else {
        //alert('loadSitePage: div not found for id: '+name);
      }
    }
  }

  //
  if( !pageInfo['isDefault'] ) {
    // set defaults for unset divs
    loadSitePage( siteStructure['default'] );

    // Don't use hasSubcontent() here because the content might not have been
    // loaded yet (the http requests were added asynchronously)
    var hideSubcontent =
         fullwidth ||
         (clearedDivs[ 'subcontent1' ] && clearedDivs[ 'subcontent2' ] ) ||
         (!loadedDivs[ 'subcontent1' ] && !loadedDivs[ 'subcontent2' ] );

    showSubcontent( !hideSubcontent, emptyMargin && !fullwidth );
  }
}

// Returns true if the subcontent DIVs exist and have html content in them,
// false otherwise.
function hasSubcontent() {
    var subcontent = document.getElementById( 'subcontent' );
    var subcontent1 = document.getElementById( 'subcontent1' );
    var subcontent2 = document.getElementById( 'subcontent2' );

    return subcontent && (
           (subcontent1 && subcontent1.innerHTML && subcontent1.innerHTML.length > 5) ||
           (subcontent2 && subcontent2.innerHTML && subcontent2.innerHTML.length > 5)
           );
}

// Makes the subcontent DIVs visible (true) or invisible (false).
// When the subcontent is not visible, an empty margin can be added
// on the left.
function showSubcontent(show, addEmptyMarginOnLeft) {
  var maincontent = document.getElementById( 'maincontent' );
  var subcontent = document.getElementById( 'subcontent' );
  var subcontent1 = document.getElementById( 'subcontent1' );
  var subcontent2 = document.getElementById( 'subcontent2' );
  if( !maincontent ) return; // precaution

  if( show ) {
    if( subcontent && subcontent1 && subcontent2 ) {
      subcontent1.style.padding = '10px';
      subcontent2.style.padding = '10px';
      subcontent.style.width = '288px';
    }

    maincontent.style.marginLeft = '25px';
    maincontent.style.width = '444px';
  } else {
    if( subcontent && subcontent1 && subcontent2 ) {
      subcontent1.style.padding = '0px';
      subcontent2.style.padding = '0px';
      subcontent.style.width = '0px';
    }

    if( !addEmptyMarginOnLeft ) {
      maincontent.style.marginLeft = '25px';
      maincontent.style.width = '732px';
    } else {/*as designed with empty part on left*/
      maincontent.style.marginLeft = '252px';
      maincontent.style.width = '505px';
    }
  }
}


// Fill the 'crumbs' div that shows the currently select path in the menu
function createCrumbs(pagesInfo, pagesName, pageInfo, pageName) {
  var html = '';
  if( !pagesInfo ) {
    if( window.pageName ) {
      pageName = window.pageName;
      for(var key in siteStructure) {
        pagesInfo = siteStructure[key];
        if( pagesInfo.pages && pagesInfo.pages[pageName] ) {
          pagesName = key;
          pageInfo = pagesInfo.pages[pageName];
          break;
        }
      }
    }
    if( !pagesInfo ) return;
  }

  if( pagesName && pageName && pagesInfo['label'] ) {
    html += '<a href="' + urlBase + 'index.php/' + pagesName + '">' + pagesInfo['label'] + '</a> ';
    if( pageInfo['label'] ) {
      html += '&gt; <a href="' + urlBase + 'index.php/' + pageName + '">' + pageInfo['label'] + '</a> ';
    }

    var crumbsDiv = document.getElementById( 'crumbs' );
    if( crumbsDiv ) {
      crumbsDiv.innerHTML = html;
    }
  }
}


// Create the menu list from siteStructure
function createMenu(currentPage) {
  // set menu html in div
  var menuDiv = document.getElementById( 'menu' );
  if( menuDiv ) {
    menuDiv.innerHTML = getMenuHtml( currentPage,/*asMenu=*/true );
  }
}

// Create the html for the sitemap page and return it.
function getSitemap() {
  var html = '';

  html += '<h2>Tiobe Software: Site Map</h2>';
  html += getMenuHtml(null,/*asMenu=*/false);

  return html;
}

// To be called when a menu header is hover over. Sets hover background color and
// shows child ul when hovering and hides it when moving out.
//
// menu    Menu node
// isOver  True when the mouse cursor is over the menu, false otherwise.
//
function hoverMenu(menu,isOver) {
  var isCurrent    = menu.attributes.isCurrent && menu.attributes.isCurrent.value == 'true';
  var isLeaf       = menu.attributes.isLeaf && menu.attributes.isLeaf.value == 'true';
  var colorCurrent = '#1067AA';
  var colorHover   = '#00579a';
  var colorIdle    = isLeaf ? '#2771a9' : '#679bc3';
  var div          = isLeaf ? menu.parentNode.parentNode : null;

  var ulTags = menu.getElementsByTagName( 'ul' );
  var ul = (ulTags && ulTags.length > 0 ? ulTags.item(0) : null);

  menu.style.background = isOver ? colorHover : (isCurrent ? colorCurrent : colorIdle);
  if( ul ) ul.style.visibility = isOver ? 'visible' : 'hidden';
}

// Returns the html for the menu of all tiobe webpages
//
// currentPage     Highlights the given name, or null for no highlight
// asMenu          Adds hovering event handling and menu CSS when set
// asAbsolute      Shows filenames instead of index.php/page urls when set
// asSpider        Set when creating a spider page.
//
function getMenuHtml(currentPage,asMenu,asAbsolute,asSpider) {
  var html = '';
  var rel;

  //
  if( location.href.indexOf('index.') >= 0 ) {
    rel = urlBase;
  } else {
    rel = '';
    if( !asAbsolute ) {
      var start = location.href.indexOf('content/')+8;
      for(var i=start+1; i>0; i=location.href.indexOf('/',i+1)) rel += '../';
    }
  }

  //html += '<pre><xmp>'; asMenu=true; // debug

  //
  html += '<ul id="menuList">\n';

  for(var pagesName in siteStructure) {
    if( pagesName == 'default' ) continue;

    var pagesInfo = siteStructure[ pagesName ];
    if( pagesInfo['hide'] ) continue;
    if( pagesInfo['nomenu'] && asMenu && !asSpider ) continue;
    if( pagesInfo['nositemap'] && !asMenu && !asSpider ) continue;
    if( pagesInfo['nospider'] && asSpider ) continue;

    var pagesLabel= pagesInfo[ 'label' ];
    if( !pagesLabel ) pagesLabel = pagesName;

    var isCurrent = ( pagesName == currentPage );
    //if( pagesInfo['relocate'] ) pagesName = pagesInfo['relocate'];

    var pages = pagesInfo['pages'];

    // find if a child is current, which also makes the parent light up
    for(var pageName in pages) {
      if( pageName == currentPage ) {
        isCurrent = true;
        break;
      }
    }

    // colors & showing of menus
    var colorCurrent = '#1067AA';
    var onHover = asMenu ? ' onMouseOver="hoverMenu(this,true);" onMouseOut="hoverMenu(this,false);"' : '';
    var bg = ( isCurrent ? ' style="background: '+colorCurrent + ';"' : '' );
    html += '\t<li'+bg+onHover+ (asMenu ? ' isCurrent="'+isCurrent+'"' : '') + '>';
    if( !asAbsolute ) {
      html += '<a href="' + rel + 'index.php/' + pagesName + '">' + pagesLabel + '</a>\n'
    } else {
      html += pagesLabel + '\n';
    }

    if( pages ) {
      html += '\t\t<ul>\n';

      for(var pageName in pages) {
        var pageInfo = pages[pageName];
        if( pageInfo['nomenu'] && asMenu && !asSpider ) continue;
        if( pageInfo['nositemap'] && !asMenu && !asSpider ) continue;
        if( pageInfo['nospider'] && asSpider ) continue;

        var url = 'index.php/' + pageName;
        if( asAbsolute && pageInfo['maincontent'] ) {
          url = 'content/' + pageInfo['maincontent'];
        }
        if( pageInfo['relocate'] ) {
          var loc = pageInfo['relocate'];
          if( loc.indexOf(':') > 0 || loc.indexOf('/') != loc.lastIndexOf('/') ) {
            url = loc;
          }
        }

        var pageLabel = pageInfo['label'];
        if( !pageLabel ) pageLabel = pageName;
        pageLabel = pageLabel.replace( / /g, '&nbsp;' );

        if( !/^http:\/\//.test( url ) ) url = rel + (asMenu || !asSpider ? '' : 'index.php/') + url;

        html += '\t\t\t<li'+onHover+ (asMenu ? ' isLeaf=true' : '') + '>';
        html += '<a href="' + url + '">' + pageLabel + '</a></li>\n';
      }

      html += '\t\t</ul>\n';
    }
    if( !asMenu ) html += '\t\t<br/>\n';
    html += '\t</li>\n';
  }
  html += '</ul>\n';

  //html += '</xmp></pre>'; // debug

  return html;
}

// Adds the spider page to the document that should be copied into spiderpage.html
// so that web spiders of search engines can collect keywords from the tiobe site.
function printSpiderPage() {
  /*
  // collect all html files
  var filenames = Array();

  // Each siteStructure key contains pages array.
  // Each array contains keys that might have a 'html' value.
  // Collect all these values.
  for(var key in siteStructure) {
    var pages = siteStructure[key]['pages'];
    if( pages ) {
      for(var pageKey in pages) {
        var page = pages[pageKey];
        for(var itemKey in page) {
          var value = page[itemKey];
          if( typeof value == 'string' && value.match( /\.*html?$/ ) ) {
            // as map to prevent double names
            filenames[value] = true;
          }
        }
      }
    } else {
      for(var itemKey in siteStructure[key]) {
        var value = siteStructure[key][itemKey];
        if( typeof value == 'string' && value.match( /\.*html?$/ ) ) {
          // as map to prevent double names
          filenames[value] = true;
        }
      }
    }
  }
  */

  var html = '';
  html += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n';
  html += '<html>\n';
  html += '<head>\n';
  html += '\t<title>TIOBE Website Spider Page</title>\n';
  html += '\t<meta name="description" content="Tiobe Software B.V. Company Homepage" />\n';
  html += '\t<meta name="Keywords" content="tiobe,software,quality,tics,clocksharp,jacobe,tpci" />\n';
  html += '</head>\n';
  html += '<body>\n\n';
  html += 'Because this site is implemented using client-side includes\n';
  html += 'through JavaScript and AJAX HttpRequests, spiders are not able\n';
  html += 'to find out what content exists on this site. Therefore this\n';
  html += 'page is available to point spiders to all available content on\n';
  html += 'the www.tiobe.com site.\n\n';

  html += getMenuHtml( /*pageName=*/null, /*asMenu=*/false, /*asAbsolute=*/true, /*asSpider=*/true );

  /*
  for(var filename in filenames) {
    html += '<a href="content/'+filename+'">';
    html += filename.replace( /\.html?$/, '' );
    html += '</a> |\n';
  }
  */
  html += '\n';
  html += '</body>\n';
  html += '</html>\n';

  //
  html = html.replace( /</g, '&lt;' );
  html = html.replace( />/g, '&gt;' );
  html = '<pre>\n' + html + '</pre>';

  document.write( html );
  document.close();
}
