// DJ Steveboy: Playlist Displayer
// Copyright (c) 2006-2007 Orbona
// Version 1.0
// Release Date: 2007-10-22
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: djsteveboy_playlist.user.js
// Please reference the original file name when contacting me regarding this
// script.
//
// This software is licensed under the CC-GNU GPL:
// http://creativecommons.org/license/cc-gpl
//
// ----------------------------------------------------------------------------
// DESCRIPTION
//
// Adds the track listing to the expanded "archive" entries on DJ Steveboy's
// site. Also modifies the "Download" link under the latest offering so that
// it actually initiates a download, instead of expanding the section that
// explains how to download a file.
// ----------------------------------------------------------------------------

// ==UserScript==
// @name            DJ Steveboy: Playlist Displayer
// @description     Includes the track listing when expanding the "archive" entries on DJ Steveboy's site
// @namespace       http://www.orbona.com/greasemonkey/
// @include         http://www.djsteveboy.com/groovelectric.html
// @include         http://www.djsteveboy.com/podrunner.html
// @include         http://www.djsteveboy.com/intervals.html
// @include         http://djsteveboy.com/groovelectric.html
// @include         http://djsteveboy.com/podrunner.html
// @include         http://djsteveboy.com/intervals.html
// ==/UserScript==

String.prototype.startsWith = function(s) { return this.indexOf(s)==0; }

String.prototype.endsWith = function (str) {
  var offset = this.length - str.length;
  return offset >= 0 && this.lastIndexOf(str) === offset;
 };

// ----------------------------------------------------------------------------
// Retrieves the playlist based on the "id" associated with the button/link/
// whatever that was clicked
// ----------------------------------------------------------------------------
function showPlaylist(event) {
   var target = event ? event.target : this;
   var id = target.id;

   if (!id && target.parentNode) id = target.parentNode.id;
   if (id.startsWith('link')) id = id.substr(4)

   unsafeWindow.retrievePlaylist(id);
}

// ----------------------------------------------------------------------------
// Main function that does everything described in the description area above.
// ----------------------------------------------------------------------------
function doIt() {
   var currentDownloadSection;

   if (document.URL.endsWith('intervals.html'))
      currentDownloadSection = document.getElementById('qC') ;
   else
      currentDownloadSection=document.getElementById('qB') || document.getElementById('q2');

   var regexID = /showParagraph\('([^)]+)'\)/im;
   var allShowParagraphs="";
   var i, archiveDiv, expandCollapseAll, actualDownloadLink, oldDownloadLinks, oldDownloadLink, thisLink, paragraphID, pID, script, scriptText, paragraphLinks, divsSetHeight,divSetHeight;

   if (currentDownloadSection) {
      actualDownloadLink=document.evaluate(".//A[contains(@href,'.mp3')]", currentDownloadSection, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);

      if (actualDownloadLink.snapshotLength) {
         actualDownloadLink = actualDownloadLink.snapshotItem(0).href;
         oldDownloadLinks = document.evaluate(".//A[contains(@href, '" + currentDownloadSection.id + "')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);

         for (i=0; i < oldDownloadLinks.snapshotLength; i++) {
            oldDownloadLink = oldDownloadLinks.snapshotItem(i);
            if (oldDownloadLink.innerHTML.match(/download/i))
               oldDownloadLink.href = actualDownloadLink;
         }
      }
   }

   archiveDiv= document.getElementById('qE') || document.getElementById('qD') || document.getElementById('q4');
   if (!archiveDiv) return false;

   expandCollapseAll = document.createElement('div');
   expandCollapseAll.innerHTML='<div><table width="324" height="22" border="1" align="center" cellpadding="0" cellspacing="0" bordercolor="#CCCCCC" bgcolor="#000000"><tr><td width="287" bgcolor="#003366"><div align="center"><a href="#" onclick="toggleAllParagraphDisplay(); return false;" id="expandCollapseAll">Expand All Descriptions</a></div></td></tr></table></div>';

   archiveDiv.insertBefore(expandCollapseAll, archiveDiv.firstChild);

   paragraphLinks=document.evaluate(".//A[contains(@href,'javascript:showParagraph')]", archiveDiv, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);

   divsSetHeight= document.evaluate('//div[@class="style4"]', document,  null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
   fixHeight:
   for (i=0; i < divsSetHeight.snapshotLength; i++) {
      divSetHeight = divsSetHeight.snapshotItem(i);
      if (divSetHeight.style.height=="500px") {
         divSetHeight.style.height=null;
         break fixHeight;
      }
   }

   for (i=0; i < paragraphLinks.snapshotLength; i++) {
      thisLink = paragraphLinks.snapshotItem(i);
      if (paragraphID = regexID.exec( thisLink.href ) ) {
         pID = paragraphID[1];
         if (pID) {
            //writing the code on the fly as we're going through the items we are interested in
            allShowParagraphs += "   forceToggleParagraphDisplay(displayStyle, '" +pID + "');\n";
            thisLink.id ='link' + pID;

            thisLink.addEventListener('click', showPlaylist, true);
         } //have a paragraph id
      } //paragraph match
   } //for all showParagraph links

   // yes, this could be written in a loop similar to the above
   // but since we already know the paragraph ids, it seemed more efficient to not
   // search for the ids again

   if (allShowParagraphs) {
      script = document.createElement('script');
      script.type = 'text/javascript';


      scriptText = "var showingAll=false;\n\nfunction forceToggleParagraphDisplay(displayStyle, parID) {\n var paragraph = document.getElementById(parID);\n   if (paragraph != null) paragraph.style.display = displayStyle;\n   if (showingAll) retrievePlaylist(parID);\n}\n";

      scriptText += "\nfunction toggleAllParagraphDisplay() {\n   showingAll=!showingAll;\n   var displayStyle= showingAll ? 'block' : 'none';\n   var expandCollapseAll = document.getElementById('expandCollapseAll');\n   expandCollapseAll.innerHTML= !showingAll ? 'Expand All Descriptions' : 'Collapse All Descriptions';\n" + allShowParagraphs + "}\n";

      scriptText += "\nfunction retrievePlaylist(id) {\n   var paragraph, trackDiv, popupLinks, url, http, tracks, actualListing, track;\n   var counter=0;\n   var tracksRetrieved= document.getElementById('tracks'+id);\n   if (tracksRetrieved) return;\n   paragraph = document.getElementById(id);\n\n   if (!paragraph ) return;\n\n   trackDiv = document.createElement('div');\n   trackDiv.innerHTML = '<div id=\\'tracks' + id +'\\'>Retrieving playlist...</div>';\n   paragraph.appendChild(trackDiv);\n\n   popupLinks=document.evaluate(\"//DIV[@id='\" + id + \"']//p//A[contains(@href,'javascript:popUp')]\",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);\n\n   if (popupLinks.snapshotLength !=1) return;\n\n   url = '/' +  popupLinks.snapshotItem(0).href.substring(18, popupLinks.snapshotItem(0).href.length-2);\n\n   http = new XMLHttpRequest();\n   http.open('GET',url,true)\n   http.send(null);\n\n   http.onreadystatechange = function() {\n      if (http.readyState==4)  {\n         if (http.status==200) {\n            tracks = http.responseText.replace(/<[^>]+>/gim, '');\n            tracks = tracks.split('\\n');\n\n            actualListing='';\n            for (var i=0; i <tracks.length; i++) {\n               track = tracks[i].replace(/^\\s+/g, '').replace(/\\s+$/g, '');\n\n               if (track.match(/^\\d+\./)) {\n                  if (counter++>0)actualListing+='<br />\\n';\n                  actualListing+= track;\n               }\n            }\n\n            trackDiv.innerHTML = '<div id=\\'tracks' + id +'\\'>' + actualListing  + '</div>';\n\n         }\n         else{\n            trackDiv.innerHTML = '<div id=\\'tracks' + id +'\\'>Unable to retrieve playlist.</div>';\n            alert('Problem retrieving playlist data for id: ' + id)\n         }\n      } //if ready\n   } //function definition for readystatechange\n}";

      //GM_log(scriptText);
      script.innerHTML = scriptText;
      document.body.appendChild(script);
   }
}

// ------------------END OF FUNCTIONS -----------------------------

window.addEventListener("load", function() { doIt(); }, false);
