///////////////////////////////////////////////////////////////////
//// Constants

const kArtistGrouping = 10;
const kAlbumCols = 4;
const kFloaterOffset = 30;
const kDefaultCoverUrl = "http://joehewitt.com/media/covers/blank.jpg";

///////////////////////////////////////////////////////////////////
//// Globals

var gSelectedArtists = null;
var gAlbumFloater = null;
var gLastFloater = null;
var gPlaybookElt = null;
var gHandleOffsetX = 0, gHandleOffsetY = 0

var gGenre = null, gYear = null;

///////////////////////////////////////////////////////////////////
//// Misc

function initMusic()
{
  getGenres(onGenresLoaded);
}

/////////////////////////////////////////////////////////////////////
//// Load handlers

function onGenresLoaded(aDoc)
{
  if (!aDoc || !aDoc.documentElement || !aDoc.documentElement.firstChild)
    return;

  var selectElt = document.getElementById("genreSelect");

  var genreElt = aDoc.documentElement.firstChild;  
  while (genreElt) {
    if (genreElt.nodeType == 1) {
      var optionElt = document.createElement("option");
      optionElt.setAttribute("value", genreElt.getAttribute("value"));
      optionElt.appendChild(document.createTextNode(genreElt.getAttribute("value")));
      selectElt.appendChild(optionElt);
    }
    genreElt = genreElt.nextSibling;
  }

  getYears(onYearsLoaded);
}

function onYearsLoaded(aDoc)
{
  if (!aDoc || !aDoc.documentElement || !aDoc.documentElement.firstChild)
    return;

  var selectElt = document.getElementById("yearSelect");

  var decadeElt = aDoc.documentElement.firstChild;  
  while (decadeElt) {
    if (decadeElt.nodeType == 1) {
      var optionElt = document.createElement("option");
      optionElt.setAttribute("value", decadeElt.getAttribute("value"));
      optionElt.appendChild(document.createTextNode(decadeElt.getAttribute("value") + "0s"));
      selectElt.appendChild(optionElt);

      var optGroupElt = document.createElement("optgroup");
      selectElt.appendChild(optGroupElt);

      var yearElt = decadeElt.firstChild;
      while (yearElt) {
        if (yearElt.nodeType == 1) {
          optionElt = document.createElement("option");
          optionElt.setAttribute("value", yearElt.getAttribute("value"));
          optionElt.appendChild(document.createTextNode(yearElt.getAttribute("value")));
          optGroupElt.appendChild(optionElt);
        }
        
        yearElt = yearElt.nextSibling;
      }
    }
    decadeElt = decadeElt.nextSibling;
  }

  getArtists(kArtistGrouping, null, null, onArtistsLoaded);
}

function onArtistsLoaded(aDoc)
{
  if (!aDoc || !aDoc.documentElement || !aDoc.documentElement.firstChild)
    return;

  var artistsBoxElt = document.getElementById("stuffBox");
  var child = artistsBoxElt.lastChild;
  while (child && child != artistsBoxElt.firstChild) {
    var child2 = child.previousSibling;
    artistsBoxElt.removeChild(child);
    child = child2;
  }
  
  var artistsElt = aDoc.documentElement;
  var artistElt = artistsElt.firstChild;
  var lastArtist = "";
  while (artistElt) {
    if (artistElt.nodeType == 1) {
      var artistRowElt = document.createElement("div");
      artistRowElt.onclick = onArtistClick;
      artistRowElt.className = "artist-row";
      
      var span = document.createElement("span");
      span.className = "artist-row-artist";
      span.appendChild(document.createTextNode(artistElt.getAttribute("artist")));
      artistRowElt.appendChild(span);
      lastArtist = artistElt.getAttribute("artist");

      artistElt = artistElt.nextSibling;
      if (artistElt && artistElt.getAttribute("artist") != lastArtist) {
        span = document.createElement("span");
        span.appendChild(document.createTextNode(" to "));
        artistRowElt.appendChild(span);

        span = document.createElement("span");
        span.className = "artist-row-artist";
        span.appendChild(document.createTextNode(artistElt.getAttribute("artist")));
        artistRowElt.appendChild(span);
      }
      
      artistsBoxElt.appendChild(artistRowElt);
    }
    
    if (artistElt)
      artistElt = artistElt.nextSibling;
  }
  
  selectArtists(artistsBoxElt.childNodes[1]);
}

function onAlbumsLoaded(aDoc)
{
  if (!aDoc || !aDoc.documentElement || !aDoc.documentElement.firstChild)
    return;
  
  var albumsTableElt = document.getElementById("albumsTable");
  albumsTableElt.style.display = "none";
  while (albumsTableElt.lastChild)
    albumsTableElt.removeChild(albumsTableElt.lastChild);
  
  var albumsElt = aDoc.documentElement;
  var albumElt = albumsElt.firstChild;
  var count = 0;
  var albumRowElt = null;
  while (albumElt) {
    if (albumElt.nodeType == 1) {
      if (!albumRowElt || ++count == kAlbumCols) {
        albumRowElt = document.createElement("tr");
        albumRowElt.onclick = onAlbumClick;
        albumRowElt.className = "album-row";
        albumsTableElt.appendChild(albumRowElt);
        count = 0;
      }
      
      var albumCellElt = document.createElement("td");
      albumCellElt.className = "album-cell";
      albumCellElt.setAttribute("albumid", albumElt.getAttribute("id"));
      
      var imageUrl = albumElt.getAttribute("imagesm");
      if (!imageUrl)
        imageUrl = kDefaultCoverUrl;
        
      var coverElt = document.createElement("img");
      coverElt.className = "album-row-cover";
      coverElt.src = imageUrl;
      
      var artistElt = document.createElement("div");
      artistElt.className = "album-row-artist";
      artistElt.appendChild(document.createTextNode(albumElt.getAttribute("artist")));

      var titleElt = document.createElement("div");
      titleElt.className = "album-row-title";
      titleElt.appendChild(document.createTextNode(albumElt.getAttribute("album")));
      
      albumCellElt.appendChild(coverElt);
      albumCellElt.appendChild(artistElt);
      albumCellElt.appendChild(titleElt);
      albumRowElt.appendChild(albumCellElt);
    }
    
    albumElt = albumElt.nextSibling;
  }

  albumsTableElt.style.display = "block";
}

/////////////////////////////////////////////////////////////////////
//// Click handlers

function onArtistClick(aEvent)
{
  var t = getEventTargetByNodeName(aEvent ? aEvent.target : event.srcElement, "DIV");
  if (t)
    selectArtists(t);
}

function onAlbumClick(aEvent)
{
  var t = getEventTargetByNodeName(aEvent ? aEvent.target : event.srcElement, "TD");
  if (t) {
    getAlbum(t.getAttribute("albumid"), onAlbumLoaded);
  }
}

/////////////////////////////////////////////////////////////////////
//// Navigation

function selectArtists(aArtistsElt)
{
  if (gSelectedArtists)
    gSelectedArtists.removeAttribute("selected");
    
  gSelectedArtists = aArtistsElt;
  if (aArtistsElt) {
    aArtistsElt.setAttribute("selected", "true");

    var minArtist = aArtistsElt.firstChild.firstChild.nodeValue;
    var maxArtist = aArtistsElt.lastChild.firstChild.nodeValue;
    getAlbums(minArtist, maxArtist, gGenre, gYear, onAlbumsLoaded)  
  } 
}

/////////////////////////////////////////////////////////////////////
//// Floating Albums/Playlists

function onAlbumLoaded(aDoc)
{
  if (!aDoc || !aDoc.documentElement.firstChild)
    return;

  var albumElt = aDoc.documentElement.firstChild;
  while (albumElt && albumElt.localName != "album")
    albumElt = albumElt.nextSibling;

  if (albumElt) {
    var albumBoxElt = createAlbumBox(albumElt);
    createFloater(albumBoxElt);
  }
}

function createAlbumBox(aAlbumElt)
{
  var div = document.createElement("div");
  div.className = "album-box";
  div.setAttribute("album", "true");
  
  var imageUrl = aAlbumElt.getAttribute("imageme");
  if (!imageUrl)
    imageUrl = kDefaultCoverUrl;

  var coverElt = document.createElement("img");
  coverElt.className = "album-cover";
  coverElt.src = imageUrl;
  
  var headerElt = document.createElement("div");
  headerElt.className = "album-header";
  
  var artistElt = document.createElement("span");
  artistElt.className = "album-artist";
  artistElt.appendChild(document.createTextNode(aAlbumElt.getAttribute("artist")));
  headerElt.appendChild(artistElt);
  
  var titleElt = document.createElement("span");
  titleElt.className = "album-title";
  titleElt.appendChild(document.createTextNode(aAlbumElt.getAttribute("album")));
  headerElt.appendChild(titleElt);

  var trackTableElt = document.createElement("table");
  trackTableElt.setAttribute("cellSpacing", "0");
  trackTableElt.setAttribute("cellPadding", "0");
  trackTableElt.setAttribute("border", "0");
  
  var trackElt = aAlbumElt.firstChild;
  var trackIndex = 1;
  while (trackElt) {
    if (trackElt.localName == "track") {
      var trackRowElt = document.createElement("tr");
      trackRowElt.setAttribute("trackid", trackElt.getAttribute("id"));
      trackRowElt.className = "track-row " + (trackIndex%2 ? "odd" : "even");
      trackRowElt.onclick = onTrackClick;
      
      var trackNumElt = document.createElement("td");
      trackNumElt.className = "track-cell-index";
      trackNumElt.appendChild(document.createTextNode(trackIndex));
      
      var trackNameElt = document.createElement("td");
      trackNameElt.className = "track-cell-name";
      trackNameElt.appendChild(document.createTextNode(trackElt.getAttribute("name")));
      
      trackRowElt.appendChild(trackNumElt);
      trackRowElt.appendChild(trackNameElt);
      trackTableElt.appendChild(trackRowElt);
      
      ++trackIndex;
    }
    trackElt = trackElt.nextSibling;
  }

  div.appendChild(headerElt);
  div.appendChild(coverElt);
  div.appendChild(trackTableElt);
  
  return div;
}

function createFloater(aChild)
{
  var div = document.createElement("div");
  div.className = "album-floater";
  div.style.zIndex = "100000";

  var handleElt = document.createElement("div");
  handleElt.className = "album-floater-handle";
  handleElt.onmousedown = onHandleMouseDown;
    
  var closeElt = document.createElement("div");
  closeElt.className = "album-floater-close";
  closeElt.onclick = onCloseBoxClick;

  div.appendChild(handleElt);
  div.appendChild(closeElt);
  
  if (gLastFloater) {
    div.style.top = (gLastFloater.offsetTop + kFloaterOffset) + "px";
    div.style.left = (gLastFloater.offsetLeft + kFloaterOffset) + "px";
  }
  
  gLastFloater = div;

  div.appendChild(aChild);
  document.body.appendChild(div);  
  
  return div;
}

function onHandleMouseDown(aEvent)
{
  gAlbumFloater = aEvent.target.parentNode;

  gAlbumFloater.style.zIndex = "100001";
  
  gHandleOffsetX = gAlbumFloater.offsetLeft - aEvent.clientX;
  gHandleOffsetY = gAlbumFloater.offsetTop - aEvent.clientY;

  document.onmouseup = onHandleMouseUp;
  document.onmousemove = onHandleMouseMove;
}

function onHandleMouseUp(aEvent)
{
  document.onmouseup = null;
  document.onmousemove = null;
}

function onHandleMouseMove(aEvent)
{
  gAlbumFloater.style.top = (aEvent.clientY+gHandleOffsetY) + "px";
  gAlbumFloater.style.left = (aEvent.clientX+gHandleOffsetX) + "px";
}

function onCloseBoxClick(aEvent)
{
  var t = getEventTargetByNodeName(aEvent ? aEvent.target : event.srcElement, "DIV");
  if (t.parentNode == gLastFloater)
    gLastFloater = gLastFloater.previousSibling;

  document.body.removeChild(t.parentNode);
}

/////////////////////////////////////////////////////////////////////
//// Playbook

function onTrackClick(aEvent)
{
  var t = getEventTargetByNodeName(aEvent ? aEvent.target : event.srcElement, "TR");  
  var trackId = rowElt.getAttribute("trackid");
  var trackName = rowElt.lastChild.firstChild.nodeValue;
  var artist = "artist";
  var album = "album";
  
  var playbookForm = createPlaybookForm(trackId, trackName, artist, album);
  createFloater(playbookForm);
  
  playbookForm.childNodes[1].childNodes[1].focus();
}

function createPlaybookForm(aTrackId, aTrackName, aArtist, aAlbum)
{
  var div = document.createElement("div");
  div.className = "playbook-form";
  
  // Create the track header.
  var headerElt = document.createElement("div");
  headerElt.className = "playbook-form-header";
  
  var spanElt = document.createElement("span");
  spanElt.className = "playbook-form-artist";
  spanElt.appendChild(document.createTextNode(aArtist));
  headerElt.appendChild(spanElt);
  
  spanElt = document.createElement("span");
  spanElt.className = "playbook-form-track";
  spanElt.appendChild(document.createTextNode(aTrackName));
  headerElt.appendChild(spanElt);

  spanElt = document.createElement("span");
  spanElt.className = "playbook-form-album";
  spanElt.appendChild(document.createTextNode("(" + aAlbum + ")"));
  headerElt.appendChild(spanElt);

  div.appendChild(headerElt);

  // Create the name input field.
  var rowElt = document.createElement("div");
  rowElt.className = "playbook-form-row";
  
  var labelElt = document.createElement("span");
  labelElt.className = "playbook-form-label";
  labelElt.appendChild(document.createTextNode("Name"));
  rowElt.appendChild(labelElt);

  var inputElt = document.createElement("input");
  inputElt.setAttribute("cols", "40");
  inputElt.setAttribute("field", "name");
  inputElt.setAttribute("type", "text");
  inputElt.className = "playbook-form-input";
  rowElt.appendChild(inputElt);
  
  div.appendChild(rowElt);
  
  // Create the email input field.
  rowElt = document.createElement("div");
  rowElt.className = "playbook-form-row";
  
  labelElt = document.createElement("span");
  labelElt.className = "playbook-form-label";
  labelElt.appendChild(document.createTextNode("E-Mail"));
  rowElt.appendChild(labelElt);

  var nameInputElt = document.createElement("input");
  nameInputElt.setAttribute("cols", "40");
  nameInputElt.setAttribute("field", "email");
  nameInputElt.setAttribute("type", "text");
  nameInputElt.className = "playbook-form-input";
  rowElt.appendChild(nameInputElt);
  
  div.appendChild(rowElt);

  // Create the comments textarea.
  inputElt = document.createElement("textarea");
  inputElt.setAttribute("cols", "50");
  inputElt.setAttribute("rows", "4");
  inputElt.setAttribute("field", "comments");
  inputElt.setAttribute("type", "text");
  inputElt.className = "playbook-form-textarea";
  div.appendChild(inputElt);

  // Create the submit button.
  var btnElt = document.createElement("button");
  btnElt.className = "playbook-form-button";
  btnElt.appendChild(document.createTextNode("Add Song to Playbook"));
  div.appendChild(btnElt);
  
  return div;
}

function viewPlaybook()
{
  if (!gPlaybookElt || !gPlaybookElt.parentNode)
    getPlaybook(0, 10, onPlaybookLoaded);
}

function onPlaybookLoaded(aDoc)
{
  if (!aDoc)
    return;

  var playbookElt = document.createElement("div");
  playbookElt.className = "playbook-box";
  
  var entryElt = aDoc.documentElement.firstChild;
  while (entryElt) {
    if (entryElt.localName == "entry") {
      // Find all the data elements within the entry.
      var commentsElt = null, albumElt = null, trackElt = null;
      var child = entryElt.firstChild;
      while (child) {
        if (child.localName == "comments")
          commentsElt = child;
        if (child.localName == "album")
          albumElt = child;
        if (child.localName == "track")
          trackElt = child;
        child = child.nextSibling;
      }
      
      var entryRowElt = document.createElement("div");
      entryRowElt.className = "playbook-entry";
      
      // Create the track header box.
      var trackHeaderElt = document.createElement("div");
      trackHeaderElt.className = "playbook-entry-header";
        
      var trackArtistElt = document.createElement("span");
      trackArtistElt.className = "playbook-entry-artist";
      trackArtistElt.appendChild(document.createTextNode(albumElt.getAttribute("artist")));
      trackHeaderElt.appendChild(trackArtistElt);
      
      var trackNameElt = document.createElement("span");
      trackNameElt.className = "playbook-entry-track";
      trackNameElt.appendChild(document.createTextNode(trackElt.getAttribute("name")));
      trackHeaderElt.appendChild(trackNameElt);

      // Create the byline box.
      var bylineElt = document.createElement("div");
      bylineElt.className = "playbook-entry-byline";
      bylineElt.appendChild(document.createTextNode("suggested by"));

      var authorElt = document.createElement("a");
      authorElt.className = "playbook-entry-author";
      authorElt.setAttribute("href", "mailto: " + entryElt.getAttribute("email"));
      authorElt.appendChild(document.createTextNode(entryElt.getAttribute("author")));
      bylineElt.appendChild(authorElt);

      // Create the comments box.
      var commentBoxElt = document.createElement("div");
      commentBoxElt.className = "playbook-entry-comments";
      commentBoxElt.appendChild(document.createTextNode(commentsElt.firstChild.nodeValue));

      entryRowElt.appendChild(trackHeaderElt);
      entryRowElt.appendChild(bylineElt);
      entryRowElt.appendChild(commentBoxElt);
      playbookElt.appendChild(entryRowElt);
    }
    
    
    entryElt = entryElt.nextSibling;
  }
  
  gPlaybookElt = createFloater(playbookElt);
}

/////////////////////////////////////////////////////////////////////
//// Filters

function changeGenre(aGenre)
{
  gGenre = aGenre == "" ? null : aGenre;
  getArtists(kArtistGrouping, gGenre, gYear, onArtistsLoaded);
}

function changeYear(aYear)
{
  gYear = aYear == "" ? null : aYear;
  getArtists(kArtistGrouping, gGenre, gYear, onArtistsLoaded);
}
