/* 
nycma voices interface Javascript 
mostly handles media shows and slideshows
sets length of nav, left, and right columns

Copyright 2009, Fund for the City of New York
All rights reserved.

This source file is distributable subject to the terms of the
FCNY Open Source License. 
*/

// voices object
var voices = { "version":"1.0" }

// MediaViews Code
voices.activeView = false;
voices.activeSlide = false;
voices.views = [];
voices.MediaViewer = false;
voices.MediaViews = false;
voices.defaultView = false;

// show the MediaViewer, show a view, hide others
voices.showView = function ( id, nohash ) {
  if ( !this.MediaViewer ) return;

  // if a particular view is requested
  if ( id ) {
    
  // this block sets the active slide (if view has slides and/or is a show)
    // slide id is split from show id using semi-colon
    var slidemarker = id.indexOf( ':' );
    log("Slidemarker for",id,'is',slidemarker);
    
    // if slidemarker found, hide activeSlide, set desired slide as activeSlide
    if ( slidemarker > 0 ) {
      var slideid = id;
      id = id.substr( 0, slidemarker );
      nextSlide = $( slideid );
      log("Id is now",id,"and slideid is",slideid);
      if ( nextSlide && hasElementClass( nextSlide, "slide" ) ) {
        this.hideActiveSlide();
        this.activeSlide = nextSlide;
      }
      //log("Here",id,"and",$(id));
    }
    // no slide reference, but this is a slideshow, set first slide as activeSlide
    else if ( $(id) && hasElementClass( $(id), "show" ) ) {
      var slides = getElementsByTagAndClassName( "div", "slide", $(id) );
      if ( slides.length ) {
        // hide active slide "just in case"
        this.hideActiveSlide();
        this.activeSlide = slides[0];
      }
    }     
    // no slide ref, so decativate current slide if there is one
    else {
      this.hideActiveSlide();
    }
 // end slide handling
    
    // set the active view, hiding the current view if necessary
    var nextView = $( id );
    log("Next view will be id",id,"which resolves to",nextView);
    if ( nextView && hasElementClass( nextView, "view" ) ) {
      this.hideActiveView();
      this.activeView = nextView;
    }
  }
  
  // show the viewer
  if ( this.MediaViewer.style.display=='none' ) {
    this.MediaViewer.style.display = 'block';
    log("Showing MediaViewer");
  }
  
  // now activeView is the next View, or not...
  if ( !this.activeView ) {
    log("No active view");
    this.closeAll();
    return;
  }
 
  //introspect( this.activeView );
  var activeNode = $('MediaViews').replaceChild( this.defaultView, this.activeView );
  this.MediaViewer.insertBefore( activeNode, this.MediaViewer.firstChild );
  signal( this.activeView, "activate" );
  log("Activated view",this.activeView.id);
   
  // and maybe activeSlide is the next slide?
  if ( this.activeSlide ) {
    log("Active Slide",this.activeSlide.id);
    this.activeSlide.style.display = 'block';
  }
  
  // can hash be set? chop off view
  var hashid = id.substr( 0, id.indexOf( "view" ) );
  window.location.hash = hashid;
  
  
  // make sure column adjustments get made
  /**
  if ( $("Main").heightControl ) {
    var dimNav = getElementDimensions( $('Nav') );
    var dimMain = getElementDimensions( $('Main') );
    var dimRight = getElementDimensions( $('Right') );
    var maxh = Math.max( Math.max( dimNav.h, dimMain.h-40 ), dimRight.h );
    log( "Dimensions now (Nav, Main, Right)",dimNav.h, dimMain.h, dimRight.h, " (Maxh)", maxh );
    $("Nav").style.minHeight = maxh + "px";
    $("Main").style.minHeight = maxh + "px";
    $("Right").style.minHeight = maxh + "px";
  }
  **/
  
  return;
}

// click handler
voices.controlClick = function ( e ) {
  e.stop();
  var target = e.target();
  // find parent link if necessary
  if ( !target.hash ) {
    target = target.parentNode;
  }
  if ( !target.hash ) {
    log("Controller unable to find link near click, giving up");
    return;
  }
  var viewid = target.hash.substr(1) + "view";
  log("Controller dispatch",viewid,"from",target);
  this.showView( viewid );
  var videoid = getNodeAttribute( $(viewid), "videoid" );
  if ( videoid ) {
    log("Playing",videoid);
    window.setTimeout( "$('flowplayer"+videoid+"').DoPlay()", 1000 );
  }
}

// activation handler
voices.activate = function( element ) {
  addElementClass( element, "active" );
}
voices.deactivate = function( element ) {
  removeElementClass( element, "active" );
}

// hide viewer
voices.hideViewer = function() {
  if ( this.MediaViewer ) {
    this.MediaViewer .style.display = 'none';
  }
}

// hide active view
voices.hideActiveView = function() {
  log("Hide?");
  if ( this.defaultView.style.visibility != 'hidden' ) {
    //this.defaultView.style.visibility = 'hidden';
  }
  if ( this.activeView ) {
    log("Hide",this.activeView,"id",this.activeView.id);
    signal( this.activeView, "deactivate" );
    var activeNode = $('MediaViewer').replaceChild( this.defaultView, this.activeView );
    this.MediaViews.appendChild( activeNode );
  }
}

// hide active slide
voices.hideActiveSlide = function() {
  if ( this.activeSlide ) {
    this.activeSlide.style.display = 'none';
    this.activeSlide = false;
  }
}

// close button
voices.closeAll = function ( e ) {
  this.hideViewer();
  this.hideActiveView();
  this.hideActiveSlide();
}

// init handler
voices.init = function() {
  // set parent
  this.MediaViewer = $('MediaViewer');
  if ( !this.MediaViewer ) {
    log("No MediaViewer found, MediaViews not active");
    return;
  }
  
  this.MediaViews = $('MediaViews');
  if ( !this.MediaViews ) {
    log("No MediaViews found, MediaViews not active");
  }
  
  // set up close button if present
  if ( $('MediaViewerClose') ) {
    connect( $('MediaViewerClose'),'onclick',this,'closeAll' );
  }
  
  // find or create default view
  var defaults = getElementsByTagAndClassName( "div", "defaultview", $('MediaViewer') );
  if ( defaults.length ) {
    this.defaultView = defaults[0];
  }
  else {
    var defaultView = DIV( {"id":"defaultView","class":"view defaultview"},"<h1>Default View</h1>" );
    var mv = insertSiblingNodesBefore( this.MediaViewer.firstChild, defaultView );
    this.defaultView = defaultView;
  }
  log( "default view:", this.defaultView, "from defaults", defaults );
  
  // create a place to hang hashes
  domHashes = DIV( { "id":"domHashes", "style":"position: absolute; top: 0px; left: 0px;"}, "hashes" );
  $("top").appendChild( domHashes );
  log("hashes store appended");
  this.domHashes = $( "domHashes" );
  
  
  // find views
  var views = iterateElementsByTagAndClassName ( "div", "view", $('MediaViews'), function( views, i ) {
    voices.views.push( views[i] );
    var id = views[i].id;
    views[i].viewid = id;
    this.domHashes.appendChild( A( { "name": id, "href":"#"+id }, id ) );
    setNodeAttribute( views[i], "id", id+"view" );
    log( "Found view #", id, "is now #", views[i].id );
  });
  log("Views are", views);
  
  // find viewcontrollers
  iterateElementsByTagAndClassName ( "div", "viewcontroller", $('MediaViewer'), function( controller, i ) {
    connect( controller[i], "onclick", voices, "controlClick" );
  });
  iterateElementsByTagAndClassName ( "table", "viewcontroller", $('MediaCollection'), function( controller, i ) {
    connect( controller[i], "onclick", voices, "controlClick" );
  });
  iterateElementsByTagAndClassName ( "div", "viewcontroller", $('MediaViews'), function( controller, i ) {
    connect( controller[i], "onclick", voices, "controlClick" );
  });
  
  // find viewlinks for activation
  iterateElementsByTagAndClassName ( "a", "viewlink", $('MediaCollection'), function( viewlink, i ) {
    var view = $( viewlink[i].hash.substr(1)+"view" );
    var element  = viewlink[i];
    //log( "Viewlink",i,"follows",viewlink[i].hash,"resolves to",view,"#",view.id );
    connect( view, "activate", bind( function( e ) { voices.activate( element ); }, element ) );
    connect( view, "deactivate", bind( function( e ) { voices.deactivate( element ); }, element ) );
  });
  
  // check hash and display requested view
  var hashval = false;
  if ( window.location.hash ) {
    hashval = window.location.hash;
    if ( hashval.substr( 0, 1 )=="#" ) {
      hashval = hashval.substr( 1 ) + "view";
    }
  }
  if ( hashval ) {
    if ( !$(hashval) && !window.location.search ) {
      // id is not included in page, redirect
      log("View hashval not found,, trying redirect");
      window.location.search = '?id='+hashval;
    }
    else {
      log("Showing view",hashval);
      this.showView( hashval, 'nohash' );
    }
  }
  else {
    // show first view
    log( "Will show first:", voices.views[0].id );
    this.showView( views[0].id, 'nohash' );
  }
  
  // set up key listener system
  
  log("Media Views init finished");
}
connect(window,"ondomload",voices,"init");
