if( !window.console || !window.console.log ) {
   window.console = { log: function() {} }
}


var currentCellId = "0X0";
var gridFolder = "grid";
var grid;

var autoScrolling = false;

$( document ).ready( init );
function init() {
   addLoadingScreen();
   
   grid = $( "#grid" );
   initGrid();
   
   $( document ).scroll(
      function( e ) {
         parra( e );
         manualScrollTest( e );
      }
   ).resize( function() { scrollTo( currentCellId, 0 ); parra({ target: document }); } );
   
   setTimeout( function() { scrollTo( "1X1", 100 ); }, 500 );
   
   $( ".parra-box, .parra-box-2, .parra-box-3" ).each( 
      function() {
         
         $( this ).css({
            left: Math.round( 100 * Math.random() ) + "%",
            top: Math.round( 100 * Math.random() ) + "%"
         
         });
      
      }
   );
   
   
}


var loadingScreen;
function addLoadingScreen() {

   loadingScreen = $( "<div>" ).attr( "id", "loading-screen" ).appendTo( $( "body" ) );
   $( "<div>" ).attr( "id", "inner-loading-screen" ).html( "loading" ).appendTo( loadingScreen );
   
}

function removeLoadingScreen() {
   if( loadingScreen ) loadingScreen.remove();
}



function ieHaxx() {
   
   $( this ).find( "*" ).each( 
      function() {
         if( $( this ).css( "display" ) == 'inline-block' ) {
            $( this ).css( "display", "inline" );
         }
      }
   );
}




function initGrid() {

   $.getJSON( 
      gridFolder + "/settings.json", 
      function( data ) {
      
         grid.data( data );
         setGridCells();
      }
   );
   
}


var navPluppsSize = 15;
var navPluppsMargin = 5;
var numOfCells = 0, loadedCells = 0;

function setGridCells() {

   var args = grid.data();
   var navigation = $( "<div>" ).addClass( "grid-navigation" ).appendTo( grid );
   
   var navigationTitle = $( "<p>" ).addClass( "grid-title" ).appendTo( navigation );
   var navigationTitleEnd = navigationTitle.position().top + navigationTitle.height();
   
   var innerNavigation = $( "<div>" ).addClass( "grid-inner-navigation" ).appendTo( navigation );
   
   numOfCells = args.cells.length;
   
   var maxRow = 0, maxCol = 0;
   for( var i=0; i<args.cells.length; i++ ) {
      
      var cellId = args.cells[i].row + "X" + args.cells[i].col;
      
      var cellFile = gridFolder + "/" + args.cells[i].file + ".php?seed=" + Math.round( Math.random() * 1000 );
      var cell = $( "<div>" )
         .data( args.cells[i] )
         .addClass( "grid-cell grid-col-" + args.cells[i].col + " grid-row-" + args.cells[i].row )
         .attr({ id: "grid-cell-" + cellId })
         .appendTo( grid );
         
         
         
      if( args.cells[i].background ) {
         cell.css({ background: args.cells[i].background });
      }
         
      
      var innerCell = $( "<div>" )
         .addClass( "grid-cell-inner" )
         .appendTo( cell )
         .load( cellFile, loadedCellContent );
         
         
             
      $( "<a>" )
         .attr({ href: "javascript:;", id: "nav-" + cellId })
         .addClass( "grid-nav-plupps rounded-corners" )
         .data( args.cells[i] )
         .html( cellId + ": " + args.cells[i].name ) 
         .click( clickedGridNav )
         .css({ 
            left: ( args.cells[i].col - 1 ) * ( navPluppsSize + navPluppsMargin ) + navPluppsMargin, 
            top: ( args.cells[i].row - 1 ) * ( navPluppsSize + navPluppsMargin ) + navPluppsMargin
         })
         .hover( setGridTitle, function() { setGridTitle( { currentTarget: $( ".grid-nav-plupps.active" ) }); } )
         .appendTo( innerNavigation );
         
      maxRow = Math.max( maxRow, args.cells[i].row );
      maxCol = Math.max( maxCol, args.cells[i].col );  
   }
   
   
   innerNavigation.css({ 
      width: maxCol * ( navPluppsSize + navPluppsMargin ) + navPluppsMargin, 
      height: maxRow * ( navPluppsSize + navPluppsMargin ) + navPluppsMargin
   });  
}



function setGridTitle( e ) {
   $( ".grid-title" ).html( $( e.currentTarget ).data( "name" ) );
}


function clickedGridNav() {
   scrollTo( $( this ).data( "row" ) + "X" + $( this ).data( "col" ) );
   return false;
}


function loadedCellContent() {
   
   
   var theCell = $( this ).parent();
   
   var cellId = theCell.data( "row" ) + "X" + theCell.data( "col" );
   
   $.proxy( initTimeline, this )();
   $.proxy( initModal, this )();
   $.proxy( initSlides, this )();
   
   $( this ).find( ".grid-nav" ).click( clickedGridNav );
   $( this ).find( ".chart" ).each( initChart );
   
   
   
   if( $.browser.msie && $.browser.version < 8 ) {
      $( this ).each( ieHaxx );
   }
   
   if( ++loadedCells == numOfCells ) {
      removeLoadingScreen();
   }
}



function initSlides() {

   $( this ).find( ".slides" ).each(
      function() {
      
         var slideOpts = {};
         
         var ownOpts = $( this ).data();
         for( var i in ownOpts ) {
            var ii = $.camelCase( i );
            if( typeof( ownOpts[i] ) == 'string' && ownOpts[i] == 'true' ) ownOpts[i] = true;
            if( typeof( ownOpts[i] ) == 'string' && ownOpts[i] == 'false' ) ownOpts[i] = false;
            slideOpts[ii] = ownOpts[i];
         }
         
         $( this ).slides( slideOpts );
      }
   );
}


function initModal() {
   var theCell = $( this ).parent();
   
   $( this ).find( ".reveal-modal" ).each( 
      function() {
         
         var leftPerc = ( ( theCell.data( "col" ) - 1 ) * 100 + 50 );
         $( this ).css({ left: leftPerc + "%" }).appendTo( $( "body" ) );
      }
   );
   
   $( this ).find( ".modal-opener" ).each( 
      function() {         
         $( this ).click( 
            function() {
               $( "#" + $( this ).data( "modalid" ) ).reveal({ animation: "fade" });
            }
         );
      }
   );
}


function initChart() {
   
   var url = gridFolder + "/" + $( this ).data( "data" ) + ".json";
   $.getJSON( url, $.proxy( renderChart, this ) );

}


function renderChart( data ) {
   $.plot( $( this ), data.data, data.options );
   
   
   $( this ).bind( "plothover", 
      $.proxy( 
         function( e, pos, item ) {
         
            $( this ).find( ".chart-label" ).remove();
            
            if( item != null ) {
               var txt = item.series.label + ":" + item.series.data[0][1];
               $( this ).append( $( "<p>" ).addClass( "chart-label" ).html( txt ) );
               
            }
         }, this 
      )
   );
}


var is_scrolling = false;
var multi_scroll = false;

function scrollTo( cellId, speed ) {

   if( is_scrolling ) return;
   
   is_scrolling = true;
   speed = ( speed || speed === 0 ? speed : 3000 );
   
   var new_args = cellId.split( "X" );
   var current_args = currentCellId.split( "X" );
   
   multi_scroll = ( new_args[0] != current_args[0] && new_args[1] != current_args[1] );
   
   $( "body" ).stop();
   $.scrollTo( $( "#grid-cell-" + cellId ), speed * ( multi_scroll ? 1 : 0.5 ), { queue: multi_scroll, onAfter: afterScroll } );
   setActiveCell( cellId );
   
   
   if( speed > 0 ) $( ".grid-navigation" ).fadeTo( 200, 0.5 );
   
}


function afterScroll() {
   $( ".grid-navigation" ).fadeTo( 200, 1 );
   is_scrolling = false;
}



function setActiveCell( cellId ) {

   currentCellId = cellId;

   $( ".grid-navigation .active" ).removeClass( "active" );
   if( cellId != false ) {
      $( "#nav-"+ cellId ).addClass( "active" );   
   }
   
   setGridTitle( { currentTarget: $( ".grid-nav-plupps.active" ) });
}


function manualScrollTest( e ) {

   if( is_scrolling ) return;

   var x = $( window ).scrollLeft();
   var y = $( window ).scrollTop();
   
   var closestCellId = false;
   var closestDistance = 99999999;
   
   var sdist = Math.sqrt( Math.pow( $( document ).width(), 2 ) + Math.pow( $( document ).height(), 2 ) );
   
   var cells = $( ".grid-cell" ).each( 
      function() {
         
         var xx = $( this ).position().left;
         var yy = $( this ).position().top;
         var dist = Math.sqrt( ( x-xx ) * ( x-xx ) + ( y-yy ) * ( y - yy ) );
         
         if( dist < sdist && dist < closestDistance ) {
            closestDistance = dist;
            closestCellId = $( this ).data( "row" ) + "X" + $( this ).data( "col" );
         }
      }
   );
   
   setActiveCell( closestCellId );
}



function parra( e ) {

   $( ".grid-parra" ).each( 
      function() {
      
         var b = $( "body" );
         var w = $( e.target );
         
         var percx = w.scrollLeft() / ( w.width() - b.width() );
         var percy = w.scrollTop() / ( w.height() - b.height() );
                  
         $( this ).css({
            left: -percx * ( $( this ).width() - b.width() ),
            top: -percy * ( $( this ).height() - b.height() )
         });
      }
   )
}

















/* -------------- TIMELINE - STUFF ---------------------- */


var timelinePlayId = -1;
var timelinePlayMarker = 0;
var timer = 0;
var oldTimer = 0;
var animateSlideId = -1;

function initTimeline() {
   $( this ).find( ".timeline" ).each( 
      function() {
         
         
         $( this ).children().addClass( "timeline-element" );
         
         var args = $( this ).data();
         
         var timelineElementContainer = $( "<div>" )
            .addClass( "timeline-element-container" )
            .css({ "position": "absolute", "left": "50%", "top": "50%", width: 0, height: 0, overflow: "visible" });
         
         timelineElementContainer.appendTo( $( this ) );
            
         var sliderOpts = {
            min: parseFloat( args.start ),
            max: parseFloat( args.end ),
            step: 1,
            slide: function( e, slideObj ) { cancelTimelinePlaying(); slidingTimeline( $( this ), slideObj.value ); },
            change: function( e, slideObj ) { slidingTimeline( $( this ), slideObj.value ); }
         };
         var slider = $( "<div>" ).addClass( "slider" ).slider( sliderOpts ).data( "timeline", $( this ) ).css( "z-index", 10000 );
         
         var pWidth = $( this ).width();
         var pHeight = $( this ).height() - 20;
         
         $( this ).children( ".timeline-element" )
            .each( 
               function() {
                  
                  if( $( this ).css( "position" ) == 'static' ) {
                     $( this ).css({
                        position: "absolute",
                        left: ( pWidth - 200 ) * ( - 0.5 + Math.random() ),
                        top: ( pHeight - 100 ) * ( -0.5 + Math.random() )
                     });
                  }
                  
                  var args = {
                     left: parseFloat( $( this ).css( "left" ) ),
                     top: parseFloat( $( this ).css( "top" ) ),
                     slider: slider
                  };
                  
                  var myArgs = $( this ).data();
                  
                  for( var i in myArgs ) {
                     args[i] = myArgs[i];
                  }
                  
                  $( this ).data( "z-index", -1 );
                  
                  $( this ).data( args );
                  $( this )[0].args = args;
                  
                  $( this )
                     .hover(
                        function() { $( this ).css( "z-index", 5000 ); },
                        function() { $( this ).css( "z-index", $( this ).data( "z-index" ) ); }
                     )
                     .click( 
                        function() {
                           animateSlider( $( this ).data( "slider" ), $( this ).data( "start" ) );
                        }
                     );
               
                  $( this ).appendTo( timelineElementContainer );
               }
            );
      
         
         slider.appendTo( $( this ) );
         slidingTimeline( slider, 0 );
         
         
         $( this ).data( "slider", slider );
         
      }
   );
   
   $( this ).find( ".timeline-play-button" )
      .click( function() { playTimeline( $( "#" + $( this ).data( "timeline" ) ), $( this ).data( "speed" ) ); } );
}




function slidingTimeline( slider, val ) {
   
   slider.data( "timeline" ).find( ".timeline-element-container > *" ).each( 
      function() {
         
         var args = $( this )[0].args;
         
         var alpha = ( val >= args.start && val <= args.end ? 1 : 0 );
         
         var min = ( args.fadestart !== undefined ? args.fadestart : args.start );
         var max = ( args.fadeend !== undefined ? args.fadeend : args.end );
            
         
         if( alpha == 0 ) {
            
            if( val < args.start && args.fadestart !== undefined  && val >= args.fadestart ) {
               alpha = Math.max( ( val - args.fadestart ), 0 ) / ( args.start - args.fadestart );
            }
            
            if( val > args.end && args.fadeend !== undefined && val < args.fadeend ) {
               alpha = 2 - ( Math.max( ( args.fadeend - val ), 0 ) / ( args.fadeend - args.end ) );
            }
         }
         
         
         if( alpha != 0 ) {
            
            if( !$.browser.msie ) {
               $( this ).fadeTo( 0, alpha > 1 ? 2 - alpha : alpha );
            }
            
         
            var depth = Math.sqrt( 0.5 + alpha * 0.5 );
            if( depth > 1 ) depth = Math.pow( depth, 2 );
            
            var zIndex = ( val >= min && val <= max ? Math.round( 1000 * ( val - min ) / ( max - min ) ) : -1 );
            
            var xx = Math.round( args.left - $( this ).width() * 0.5 * depth );
            var yy = Math.round( args.top - $( this ).height() * 0.5 * depth );
            
            $( this )
               .data({ "z-index": zIndex })
               .css({ 
                  "-moz-transform": "scale("+ depth +")",
                  zoom: depth, 
                  "z-index": zIndex, 
                  left: xx, 
                  top: yy, 
                  display: "block" 
               });
            
         }
         else $( this ).css({ display: "none" });
         
      }
   );
}



function cancelSliderAnimation() {
   
   if( animateSlideId != -1 ) {
      clearTimeout( animateSlideId );
      animateSlideId = -1;
      
      return true;
   }
   
   return false;
}


function animateSlider( slider, toVal ) {
   cancelTimelinePlaying();
   cancelSliderAnimation();
   animateSlideLoop( slider, toVal );
}

function animateSlideLoop( slider, toVal ) {
   
   var currentValue = slider.slider( "value" );
   var animatingSlideSteps = ( currentValue - toVal );
   
   if( Math.abs( animatingSlideSteps ) > 0.5 ) {
      
      var speed = ( toVal - currentValue ) * 0.05;
      
      var newVal = currentValue + speed;
      if( speed > 0 ) newVal = Math.ceil( newVal );
      else newVal = Math.floor( newVal );
      
      slider.slider( "value", newVal );
      animateSlideId = setTimeout( function() { animateSlideLoop( slider, toVal ); }, 10 );
   }
   else {
      slider.slider( "value", toVal );
   }
}


var timeline_is_playing = false;

function cancelTimelinePlaying() {
   timeline_is_playing = false;
}

function playTimeline( timeline, speed ) {
   
   cancelSliderAnimation();
   
   timelinePlayMarker = 0;
   oldTimer = timer = parseInt( ( new Date() ).getTime() );
   timeline_is_playing = true;
   
   playingTimeline( timeline, speed );
   
}


function playingTimeline( timeline, speed ) {
   
   if( !timeline_is_playing ) return;
   
   var timer = parseInt( ( new Date() ).getTime() );
   var tick = ( timer - oldTimer );
   oldTimer = timer;
   
   timelinePlayMarker += tick;
   
   var val = timeline.data( "start" ) + ( timeline.data( "end" ) - timeline.data( "start" ) ) * ( timelinePlayMarker / speed );
   
   val = Math.min( timeline.data( "end" ), val );
   timeline.data( "slider" ).slider( "value", Math.round( val ) );
   
   if( val < timeline.data( "end" ) ) {
      setTimeout( function(){ playingTimeline( timeline, speed ); }, 10 );
   }
   else cancelTimelinePlaying();
}

