// ---------------------------------------------------
// BLOGTOC
// ---------------------------------------------------
// BlogToc creates a clickable Table Of Contents for
// Blogger Blogs.
// It uses the JSON post feed, and create a ToC of it.
// The ToC can be sorted by title or by date, both
// ascending and descending, and can be filtered by
// label.
// ---------------------------------------------------
// Author: Beautiful Beta
// Url: http://beautifulbeta.blogspot.com
// Version: 2
// Date: 2007-04-12
// Updated 2007-11 by Brian Holtz http://knowinghumans.net
// ---------------------------------------------------


// Current Page Reference
// copyright Stephen Chapman, 1st Jan 2005
// you may copy this function but please keep the copyright notice with it

function getURL(uri) {
uri.dir = location.href.substring(0, location.href.lastIndexOf('\/'));
uri.dom = uri.dir; if (uri.dom.substr(0,7) == 'http:\/\/') uri.dom = uri.dom.substr(7);
uri.path = ''; var pos = uri.dom.indexOf('\/'); if (pos > -1) {uri.path = uri.dom.substr(pos+1); uri.dom = uri.dom.substr(0,pos);}
uri.page = location.href.substring(uri.dir.length+1, location.href.length+1);
pos = uri.page.indexOf('?');if (pos > -1) {uri.page = uri.page.substring(0, pos);}
pos = uri.page.indexOf('#');if (pos > -1) {uri.page = uri.page.substring(0, pos);}
uri.ext = ''; pos = uri.page.indexOf('.');if (pos > -1) {uri.ext =uri.page.substring(pos+1); uri.page = uri.page.substr(0,pos);}
uri.file = uri.page;
if (uri.ext != '') uri.file += '.' + uri.ext;
if (uri.file == '') uri.page = 'index';
uri.args = location.search.substr(1).split("?");
return uri;
}
               

// global arrays

   var postTitle = new Array();     // array of posttitles
   var postUrl = new Array();       // array of posturls
   var postDate = new Array();      // array of post publish dates
   var postSum = new Array();       // array of post summaries
   var postLabels = new Array();    // array of post labels

// global variables
   var sortBy = "datenewest";       // default value for sorting ToC
   var tocLoaded = false;           // true if feed is read and ToC can be displayed
   var numChars = 250;              // number of characters in post summary
   var postFilter = '';             // default filter value


// main callback function

function loadtoc(json) {

   function getPostData() {
   // this functions reads all postdata from the json-feed and stores it in arrays
      if ("entry" in json.feed) {
         var numEntries = json.feed.entry.length;
      // main loop gets all the entries from the feed
         for (var i = 0; i < numEntries; i++) {
         // get the entry from the feed
            var entry = json.feed.entry[i];

         // get the posttitle from the entry
            var posttitle = entry.title.$t;

         // get the post date from the entry
            var postdate = entry.published.$t.substring(0,10);

         // get the post url from the entry
            var posturl;
            for (var k = 0; k < entry.link.length; k++) {
               if (entry.link[k].rel == 'alternate') {
               posturl = entry.link[k].href;
               break;
               }
            }

         // get the post contents from the entry
         // strip all html-characters, and reduce it to a summary
            if ("content" in entry) {
               var postcontent = entry.content.$t;}
            else
               if ("summary" in entry) {
                  var postcontent = entry.summary.$t;}
               else var postcontent = "";
         // strip off all html-tags
            var re = /<\S[^>]*>/g; 
            postcontent = postcontent.replace(re, "");
         // reduce postcontent to numchar characters, and then cut it off at the last whole word
            if (postcontent.length > numChars) {
               postcontent = postcontent.substring(0,numChars);
               var quoteEnd = postcontent.lastIndexOf(" ");
               postcontent = postcontent.substring(0,quoteEnd) + '...';
            }

         // get the post labels from the entry
            var pll = '';
            if ("category" in entry) {
               for (var k = 0; k < entry.category.length; k++) {
                  pll += '<a href="javascript:filterPosts(\'' + entry.category[k].term + '\')" title="Fill this table with all posts labeled \'' + entry.category[k].term + '\'">' + entry.category[k].term + '</a>; ';
               }
            var l = pll.lastIndexOf(';');
            if (l != -1) { pll = pll.substring(0,l); }
            }

         // add the post data to the arrays
            postTitle.push(posttitle);
            postDate.push(postdate);
            postUrl.push(posturl);
            postSum.push(postcontent);
            postLabels.push(pll);
         }
      }
   } // end of getPostData

// start of showtoc function body
// get the number of entries that are in the feed
//   numEntries = json.feed.entry.length;

// get the postdata from the feed
   getPostData();

// sort the arrays
   sortPosts(sortBy);
   tocLoaded = true;

   var toclink = document.getElementById("toclink");
   toclink.innerHTML = '<a href="javascript:showToc(\'Latest\');">Show Table of Contents</a>';


   // set the filter to the search label, if present
   var uri = new Object();
   getURL(uri);
   if (uri.path == 'search/label') {
      showToc( uri.page );
   } else {
      showToc('Latest');
   }
}



// filter and sort functions


function filterPosts(filter) {
// This function changes the filter
// and displays the filtered list of posts

   postFilter = filter;
   displayToc(postFilter);
} // end filterPosts

function latestPosts() {
    postFilter = 'Latest';
    displayToc(postFilter);
}

function allPosts() {
// This function resets the filter
// and displays all posts

   postFilter = '';
   displayToc(postFilter);
} // end allPosts

function sortPosts(sortBy) {
// This function is a simple bubble-sort routine
// that sorts the posts

   function swapPosts(x,y) {
   // Swaps 2 ToC-entries by swapping all array-elements
      var temp = postTitle[x];
      postTitle[x] = postTitle[y];
      postTitle[y] = temp;
      var temp = postDate[x];
      postDate[x] = postDate[y];
      postDate[y] = temp;
      var temp = postUrl[x];
      postUrl[x] = postUrl[y];
      postUrl[y] = temp;
      var temp = postSum[x];
      postSum[x] = postSum[y];
      postSum[y] = temp;
      var temp = postLabels[x];
      postLabels[x] = postLabels[y];
      postLabels[y] = temp;
   } // end swapPosts

   for (var i=0; i < postTitle.length-1; i++) {
      for (var j=i+1; j<postTitle.length; j++) {
         if (sortBy == "titleasc") { if (postTitle[i] > postTitle[j]) { swapPosts(i,j); } }
         if (sortBy == "titledesc") { if (postTitle[i] < postTitle[j]) { swapPosts(i,j); } }
         if (sortBy == "dateoldest") { if (postDate[i] > postDate[j]) { swapPosts(i,j); } }
         if (sortBy == "datenewest") { if (postDate[i] < postDate[j]) { swapPosts(i,j); } }
      }
   }
} // end sortPosts

// displaying the toc

function displayToc(filter) {
// this function creates a three-column table and adds it to the screen
   var numDisplayed = 0;
   var tocTable = '';
   var tocRow1  = '';
   var tocHead1 = 'Title';
   var tocTool1 = 'Sort list by title';
   var tocHead2 = 'Date';
   var tocTool2 = 'Sort list by date';
   var tocHead3 = '^';
   var tocTool3 = '';
   var latestN = 6;
   var latestHead = 'Top ' + latestN;
   if (sortBy == "titleasc") { 
      tocTool1 += ' (descending)';
      tocTool2 += ' (newest first)';
   }
   if (sortBy == "titledesc") { 
      tocTool1 += ' (ascending)';
      tocTool2 += ' (newest first)';
   }
   if (sortBy == "dateoldest") { 
      tocTool1 += ' (ascending)';
      tocTool2 += ' (newest first)';
   }
   if (sortBy == "datenewest") { 
      tocTool1 += ' (ascending)';
      tocTool2 += ' (oldest first)';
   }

   for (var i = 0; i < postTitle.length; i++) {
      if (filter == '' || filter == 'Latest') {
         if (filter == 'Latest' && i > (latestN -1)) { continue; }
         tocTable += '<tr><td class="toc-entry-col1">' + postDate[i] + '</td><td class="toc-entry-col2"><div class="toc-entry-col2-div">' + '<a href="' + postUrl[i] + '" title="' + postSum[i] + '">' + postTitle[i] + '</a>' +'</div></td><td class="toc-entry-col3">' + postLabels[i] + '</td></tr>';
         numDisplayed++;
      } else {
          z = postLabels[i].lastIndexOf(filter);
          if ( z!= -1) {
             tocTable += '<tr><td class="toc-entry-col1">' + postDate[i] + '</td><td class="toc-entry-col2"><div class="toc-entry-col2-div">' + '<a href="' + postUrl[i] + '" title="' + postSum[i] + '">' + postTitle[i] + '</a>' + '</div></td><td class="toc-entry-col3">' + postLabels[i] + '</td></tr>';
             numDisplayed++;
          }
      }
   }
   tocTable += '</table>';

   if (postFilter != '') {
      tocTool3 = 'Reload this table with all ' + postTitle.length + ' posts';
   }


   if (numDisplayed == postTitle.length) {
      var tocNote = 'Listing Top ' + postTitle.length;
      tocNote += ' | <a href="javascript:latestPosts();" title="';
      tocNote += 'Reload this table with just the ' + latestN + ' latest posts';
      tocNote += '">' + latestHead + '</a>';
   } else if (postFilter == 'Latest') {
      var tocNote = '';
      tocNote += 'Listing ' + latestHead + ' | ';
      tocNote += '<a href="javascript:allPosts();" title="' + tocTool3 + '">'; 
      tocNote += 'Top ' + postTitle.length;
      tocNote += '</a>';
   } else {
      var uri = new Object();
      getURL(uri);
      var tocNote = '';
      tocNote += 'Listing '
      tocNote += '<a href="http://' + uri.dom;
      tocNote += '/search/label/' + postFilter + '"';
      tocNote += ' title="Display full copies of all posts labeled \'';
      tocNote += postFilter + '\'';
      tocNote += '">Top ';
      tocNote += numDisplayed + ' Labeled \'';
      tocNote += postFilter + '\'';
      tocNote += '</a> | ';
      tocNote += '<a href="javascript:allPosts();" title="' + tocTool3 + '">'; 
      tocNote += 'Top ' + postTitle.length;
      tocNote += '</a>';
      tocNote += ' | <a href="javascript:latestPosts();" title="';
      tocNote += 'Reload this table with just the ' + latestN + ' latest posts';
      tocNote += '">' + latestHead + '</a>';
   }

   tocRow1 += '<table class="toc-table">';
   tocRow1 += '<tr class="toc-header-row">';
   tocRow1 += '<th class="toc-header-col1">';
   tocRow1 += '<a href="javascript:toggleDateSort();" title="' + tocTool2 + '">' + tocHead2 + '</a>';
   tocRow1 += '</th>';
   tocRow1 += '<th class="toc-header-col2" colspan="2">';

   tocRow1 += '<table style="width:100%";><tr><th style="text-align:center;">';
   tocRow1 += tocNote;
   tocRow1 += '</th>'

   tocRow1 += '<th style="width:2em;text-align:right">';
   tocRow1 += '<a href="javascript:hideToc();" title="Hide table of contents">';
   tocRow1 += tocHead3;
   tocRow1 += '</a>';
   tocRow1 += '</th></tr></table>';

   tocRow1 += '</th></tr>';

   var tocdiv = document.getElementById("toc");
   tocdiv.innerHTML = tocRow1 + tocTable;
} // end of displayToc

function toggleTitleSort() {
   if (sortBy == "titleasc") { sortBy = "titledesc"; }
   else { sortBy = "titleasc"; }
   sortPosts(sortBy);
   displayToc(postFilter);
} // end toggleTitleSort

function toggleDateSort() {
   if (sortBy == "datenewest") { sortBy = "dateoldest"; }
   else { sortBy = "datenewest"; }
   sortPosts(sortBy);
   displayToc(postFilter);
} // end toggleTitleSort


function showToc(filter) {
  if (filter != undefined) {
     postFilter = filter;
  }
  if (tocLoaded) { 
     displayToc(postFilter);
  }
  else { alert("Just wait... TOC is loading"); }
}

function hideToc() {
  var tocdiv = document.getElementById("toc");
  tocdiv.innerHTML = '<center><a href="javascript:showToc(\'Latest\');">Show Table of Contents</a></center>';
}