// JavaScript Document
var projectsAnimationSpeed = 500;
var projectsAnimationEasing = "easeInOutExpo";
var projectContainerIsOpen = false;

function Carousel() {
  var _this = this;
  var count = 0;
   var testVar = 0;
   
  //Private Variables
  _imgArray = [];
  _animationSpeed = 500;
  _animationEasing = "easeInOutExpo"; 
  _data = null;
  _animationComplete = true;

  //Public Variables
  this.nextBtn = null;
  this.prevBtn = null;  

  this.init = function(data, nextBtn, prevBtn, imgArray, animationSpeed, animationEasing) { 
    //Check if required elements exist
    //Check if imgArray length > 0
    //Check if document is ready
    _data = (data == 'undefined') ? _data : data;
    _this.nextBtn = (nextBtn == 'undefined') ? this.nextBtn : nextBtn;
    _this.prevBtn = (prevBtn == 'undefined') ? this.prevBtn : prevBtn; 
    _imgArray = (imgArray == 'undefined') ? _imgArray : imgArray;         
    _animationSpeed = (animationSpeed == 'undefined') ? _animationSpeed : animationSpeed;
    _animationEasing = (animationEasing == 'undefined') ? _animationEasing : animationEasing;

   //alert(_imgArray.length); 
    count = 1;
    initImages('init');
    initNav();
 
  };  

  //on item click 
  itemClick = function (direction, count) {
    //Add locked class to prevent project container from being opened mid-animation
    $('#buttonView').addClass('locked');
    
    var animationCount = 0;
    var animationLimit = 4;
  
    //Remove Click events
    removeClickEvents();
    
    //Handle optional parameter 'count'
    direction = (typeof direction == "undefined") ? 1 : direction;
    count = (typeof count == "undefined") ? 0 : count;

    //index key:
    //0 = first item visible
    //1 = second item visible
    //2 = main item 
    $.each(_imgArray, function(index, itm) {   //itm == this
      //Set index, first item is lowest
      $(this).css({'z-index':index+1});
      switch(index) {
        case 0:
          if(direction < 0) { 
            //animate right, to 0.7 alpha, animate to mid size - 365 x 200 	
	    $(itm).animate({opacity: 0, width: '215px', height: '120px', top:'76', left:'-42'}, _animationSpeed, _animationEasing, function() {
	      //Display none so that click events do not fire		  
              $(this).css({display:'none'})
 	      animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
            });
          } else if(direction > 0) {
            //animate right, to 0.7 alpha, animate to mid size - 365 x 200 			
	    $(itm).animate({opacity: 0.7, width: '365px', height: '200px', top:'34', left:'50'}, _animationSpeed, _animationEasing, function() {
              animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
	    });		
          }
  	break;			
	case 1:
          if(direction < 0) { 
            //animate right, animate to 1 alpha, animate to full size - 490 x 270			  
	    $(itm).animate({opacity: 0.4, width: '280px', height: '154px', top:'58', left:'0'}, _animationSpeed, _animationEasing, function() {
              animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
            });
          } else if(direction > 0) {
            //animate right, animate to 1 alpha, animate to full size - 490 x 270			  
	    $(itm).animate({opacity: 1, width: '480px', height: '260px', top:'0', left:'110'}, _animationSpeed, _animationEasing, function() {
              animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
            }); 	  		
          }
        break;		
        case 2:
          if(direction < 0) { 	  
            //animate out of screen, fade to 0 alpha
            $(itm).animate({opacity: 0.7, width: '365px', height: '200px', top:'34', left:'50'}, _animationSpeed, _animationEasing, function() {
              animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
	    }); 	  
	  } else if(direction > 0) {		
            //animate out of screen, fade to 0 alpha
	    $(itm).animate({opacity: 0, left:'200'}, _animationSpeed, _animationEasing, function() {
	      //Display none so that click events do not fire
	      $(this).css({display:'none'})
 	      animationCount ++;
	      if (animationCount == animationLimit) animationComplete(direction, count)			
            });		        
	  }		
        break;	 
        case 3:
	  //Logic: If the direction is backwards (-1,-2 etc) then we want to move the 4th item (3 in the array) to the front of the visible queue
          if(direction < 0) { 
 	    //animate right, animate to 0.4 alpha, animate to mid size - 365 x 200 
	    $(this).css({'z-index':4, opacity: 0, display:'inline', width:480, height:260, top:0, left:260});
	    $(itm).animate({opacity: 1, width: '480px', height: '260px', top:'0', left:'110'}, _animationSpeed, _animationEasing, function(){ 	  				  
	      //Removes first element, adds to end, thus creating reverse rotation
	      _imgArray.push(_imgArray.shift()); 
	      animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count)			
            }); 
          } 
        break;		 		
        case _imgArray.length - 1:
          //Logic: If the direction is forwards (1,2 etc) then we want to move the last item to the back of the visible queue
          if(direction > 0) {
	    $(this).css({'z-index':0, opacity: 0, display:'inline', width:215, height:120, top:76, left:-42});
            $(itm).animate({opacity: 0.4, width: '280px', height: '154px', top:'58', left:'0'}, _animationSpeed, _animationEasing, function(){
              //Removes last element, adds to start, thus creating rotation
              _imgArray.unshift(_imgArray.pop()); 
              animationCount ++;
              if (animationCount == animationLimit) animationComplete(direction, count) 
            }); 		
          }		
        break;
      }		
    }); 
  
    return;
  };
    
  initImages = function(src) { 
    //alert(count++); 
    //To allow the carousel to function, we check to make sure 5 items are present. If not, stick duplicate items in to replace.
    if(_imgArray.length < 5) {
      var newItem = null;
      $.each(_imgArray, function(index, itm) { 
        newItem = $(itm).clone();
	$(itm).parent().append(newItem);

        _imgArray.push(newItem); 
	if(_imgArray.length >= 5) return false 
      });
    }
    
  
   //Loop through array to initialise items
    $.each(_imgArray, function(index, itm) { 
      //Set index, first item is lowest
      $(this).css({'z-index':index+1});
      
      switch(index) {
        case 0:
	  $(this).css({opacity: 0.4, width: 280, height:154, top:58, left:0}); 
          //Set click event
          $(this).one("click", function(){ 
            itemClick(2); 
          });			
	    break;   
	    case 1:
	      $(this).css({opacity: 0.7, width: 365, height: 200, top:34, left:50}); 
          //Set click event
          $(this).one("click", function(){ 
            itemClick(1); 
          });		  		
	    break;   
	    case 2:
	      $(this).css({opacity: 1, width: 480, height:260, left:110, top:0}); 
          //Set click event
          $(this).one("click", function(){ 					
            itemClick(1); 
          });		  		
	    break;   	  	  
	  default:
          //hide & resize items beyond the first 3	  
	  $(this).css({opacity: 0, width:280, height:154, display:'none'}); 
          //Set click event
          $(this).one("click", function(){ 
           itemClick(1); 
          });		  		
	    break;  
	  }	
    });
  };  
  
  initNav = function() { 
    //Because sometimes init gets called without the images changing, we remove the existing event listeners in case double init occurs.
    //Remove Nav Item events
    $(_this.prevBtn).unbind('click');
    $(_this.nextBtn).unbind('click');	  
	  
    //Set nav click events
    $(_this.prevBtn).bind("click", function(){ 
      itemClick(-1);       
    });
    $(_this.nextBtn).bind("click", function(){ 
      itemClick(1); 
    });  
  };    
  
  removeClickEvents = function() { 
    //alert('Remove ze images!');
    //Remove Nav Item events
    $(_this.prevBtn).unbind('click');
    $(_this.nextBtn).unbind('click');
    
    //Loop each img, remove Click event
    $.each(_imgArray, function(index, itm) { 
      $(itm).unbind('click');
    }); 
  };  

  animationComplete = function(direction, count) {
    //alert('animationComplete');
    //Increase count
    if(direction < 0) count --; else count ++;    
     
    //If still more moves to make, recurse.
    if(count != direction) {
      itemClick(direction, count);  
    }
    else { 
      //Remove class to allow project container to be re-opened
      $('#buttonView').removeClass('locked');
    
      initImages('animationComplete'); 
      initNav(); 
    }
  };

  this.showStaticCarousel = function(container) {
   //Loop through array to initialise items
    $.each(_imgArray, function(index, itm) {     
      $(itm).clone().appendTo($(container));
    });
    removeClickEvents();    
  };

  this.hideStaticCarousel = function(container) {
    //alert('hideStaticCarousel')	  
    //initImages('hideStaticCarousel');
    //initNav();
    //Empty Static Carousel
    $(container).empty();
  };
}

//This converts a nodeList to an Array. 
//nodeList's such as what getElementsByName returns do not support all array methods such as pop(); 
//See http://htmlcssjavascript.com/javascript/the-javascript-nodelist-and-you-watch-where-you-point-that-thing-soldier/ for further explanation
function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) { 
    array[i] = obj[i];
  }
  return array;
}

//Gets height of the project container so that close icon can be dynamic
function setProjectsOffset(offset, lowerYBound) { 
  offset = $('#contentProjects').offset();
  lowerYBound = offset.top + $('#contentProjects').height()
  
  //Return both values as an object with two properties
  return { offset: offset, lowerYBound: lowerYBound }	   
}

function showCloseButton(e) {
  $('body').addClass('closeBtnActive');	
  $('#contentProjectsClose').css("display", "block");
  $('#contentProjectsClose').css('top', e.clientY - 20).css('left', e.clientX - 20);  
}

function hideCloseButton() {
  $('body').removeClass('closeBtnActive');			 
  $('#contentProjectsClose').css("display", "none");
}

//Animates various divs for the project container to open
function showProjectContainer(carouselTop) {
  if (!(projectContainerIsOpen) && _animationComplete) {
    _animationComplete = false;
    projectContainerIsOpen = true;
    var distance = $('#contentProjects').height() / 2;
    //Populate 'fake' bottom carousel (copies images to bottom carousel)
    carouselTop.showStaticCarousel($('#carouselBottom'));    
    //Hide bottom half of top carousel
    $('#carouselContainerTop').css('overflow', 'hidden');
    //Show bottom half of bottom carousel
    $('#carouselContainerBottom').css('visibility', 'visible'); 
  
    //animate divs up/down
    $('#contentTop').stop(true, true).animate({ marginTop: '+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing);       
    $('#siteControls').stop(true, true).animate({ marginTop: '+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing);               
    $('#backgroundTop').stop(true, true).animate({ marginTop: '+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing);        
    $('#contentBottom').stop(true, true).animate({ marginTop:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing);      
    $('#backgroundBottom').stop(true, true).animate({ marginTop:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing);      
    $('#footer').stop(true, true).animate({ bottom:'+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing); 
    $('#anchorContainer').stop(true, true).animate({ top:'+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing, function() {
      _animationComplete = true;			
      $("#background").addClass('carouselOpenIEFix');
      Events.dispatchEvent(AnimationEvent.ANIMATION_COMPLETE);	 			  
    }); 
    
    //Show-Hide close button
   /* $('#buttonView').animate({ opacity:0}, projectsAnimationSpeed, projectsAnimationEasing, function() { 
      $('#buttonView').css('display', 'none');
      $('#buttonClose').css('display', 'block');
     
      //Dispatch animation Complete event
      Events.dispatchEvent(AnimationEvent.ANIMATION_COMPLETE);
    });   
    
    $('#buttonClose').stop(true, true).animate({ opacity:100 }, projectsAnimationSpeed, projectsAnimationEasing);    */     
  }
} 

//Animates various divs for the project container to close
function hideProjectContainer(carouselTop) {
  if(projectContainerIsOpen && _animationComplete) {
    $("#background").removeClass('carouselOpenIEFix');	  
    _animationComplete = false;
    projectContainerIsOpen = false;
	  
    var distance = $('#contentProjects').height() / 2;
 
    //animate divs up/down
    $('#contentTop').stop(true, true).animate({ marginTop:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing, function(){
      //Once animation has completed, hide static carousel
      carouselTop.hideStaticCarousel($('#carouselBottom'));  
      //Hide bottom half of top carousel
      $('#carouselContainerTop').css('overflow', 'visible');
      //Show bottom half of bottom carousel
      $('#carouselContainerBottom').css('visibility', 'visible');     
    });  
    $('#siteControls').stop(true, true).animate({ marginTop:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing);            
    $('#backgroundTop').stop(true, true).animate({ marginTop:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing);    
    $('#contentBottom').stop(true, true).animate({ marginTop:'+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing);           
    $('#backgroundBottom').stop(true, true).animate({ marginTop:'+=-' + distance }, projectsAnimationSpeed, projectsAnimationEasing);               
    $('#footer').stop(true, true).animate({ bottom:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing); 
    $('#anchorContainer').stop(true, true).animate({ top:'+=' + distance }, projectsAnimationSpeed, projectsAnimationEasing, function() {          
    
      _animationComplete = true; 

      //Dispatch animation Complete event
      Events.dispatchEvent(AnimationEvent.ANIMATION_COMPLETE, 'CarouselClose');   
    });
  }
}

