/* Author: 
 Matthieu Aussaguel
 April 11, 2011
 */

$(function() {
  // Init the galleries
  if ($('section.media-gallery').length) Gallery.Media.init();
  if ($('section.image-gallery').length) Gallery.Image.init();

  // Init the grid
  $('#wrapper').masonry({ columnWidth: 200 });

  // init Homepage
  if ($('.page-home').length) Homepage.init();

  // init Forms
  if ($('form').length) Form.init();

  // Initialise the Grid fragment if existing
  if ($('.grid').length) $('.grid').each(function() {
    $(this).masonry({itemSelector: '.box'});
  });

  //Init the twitter profile block fragment

  var twitterBox = [];
  if ($('section.twitter-profile-block').length) $('section.twitter-profile-block').each(function() {
    twitterBox.push(new TwitterProfile(this));
  });

});


// Homepage javascript
var Homepage = {
  $pageTop    : $('#page-top'),
  $bgWrapper  : $('#bg-wrapper'),
  $imgs       : $('#bg-wrapper img'),

  init: function() {
    var that = this;

    $(window).resize(Homepage.initImgPosition);

    this.initImgPosition(function() {
      // Set the image opacity to 0
      that.$imgs.not('.first').css('opacity', 0);

      // show the gallery
      that.$bgWrapper.css('opacity', 0)
          .show()
          .animate({'opacity' : 1}, 600, 'easeOutQuad', function() {
            that.initImgRotation();
          });
    });
  },

  initImgPosition: function(callback) {

    // Calculate the image centered position
    var windowWidth = $(window).width() > 980 ? $(window).width() : 980,
        imageWidth = 2500,
        leftPosition = 0 - (imageWidth - windowWidth) / 2;

    // Update the page top width
    Homepage.$pageTop.width((windowWidth <= 1000) ? 1012 : windowWidth);

    // Reposition all the images
    Homepage.$imgs.css('left', leftPosition);

    // Trigger the callback
    if (typeof callback === 'function') callback.call();

  },

  initImgRotation: function() {
    var that = this,
        nImgs = this.$imgs.length,
        first = 1,
        timeout = 6000,
        $oldCurrent, $current, nextIndex;

    if (nImgs > 1) {
      (function() {
        if (!first) {
          // Get the current image
          $current = that.$imgs.filter('.current');

          // get the next image index
          nextIndex = ($current.index() === nImgs - 1) ? 0 : $current.index() + 1;

          // toggle the current class
          $oldCurrent = $current.removeClass('current');
          $current = that.$imgs.eq(nextIndex).addClass('current');

          // animate images
          $current.show().animate({'opacity': 1}, 1000, 'easeOutQuad');
          $oldCurrent.animate({'opacity': 0}, 1000, 'easeInQuad');

        } else {
          that.slideDownSideBlock();
          that.$imgs.filter('.first').removeClass('first').addClass('current');
          first = 0;
        }
        setTimeout(arguments.callee, timeout);
      })();
    } else {
      that.slideDownSideBlock();
    }

  },

  slideDownSideBlock: function() {
    var $sideBlock = $('#side-block:first');

    // Move the side block up and slides it down
    $sideBlock.css({'top': (0 - $sideBlock.height()), 'visibility' : 'visible'})
        .animate({'top': 0}, 1000, 'easeInOutExpo');


  }
};


//Create the Gallery Object
var Gallery = {
  Media : {
    init: function() {
      var $mediaGallery = $('section.media-gallery'),
          that = this;

      $mediaGallery.each(function() {
        var $mediasLinks = $('nav li', this),
            $gallery = $(this),
            nMedias = $mediasLinks.length,
            currentIndex = 1,
            rotationTimeout;


        var autoRotate = function() {

          rotationTimeout = setTimeout(function() {

            // trigger a rotation
            that.rotate(currentIndex, $gallery);

            // Calculate the new index
            currentIndex = ((currentIndex + 1) === nMedias) ? 0 : (currentIndex + 1);

            autoRotate();
          }, 6000)

        };

        if (nMedias > 1) autoRotate();

        $mediasLinks.click(function() {

          clearTimeout(rotationTimeout);

          // get the new Index
          var newIndex = $(this).index();

          // get the next index
          if (newIndex !== currentIndex) {
            //update current index
            currentIndex = newIndex;

            // rotate
            that.rotate($(this).index(), $gallery);
          }
          return false;
        })
      });
    },

    rotate: function(newIndex, $gallery) {
      var $medias = $('.media-gallery-items', $gallery),
          $mediasLinks = $('nav li', $gallery);


      // Hide current item
      $('.current', $medias)
          .css({'z-index': 1})
          .animate({opacity: 0}, 500, 'easeOutQuad', function() {
            $(this).hide();
          });

      // Handle the navigation
      $('.current', $gallery).removeClass('current');

      // Add the current class
      $mediasLinks.eq(newIndex).addClass('current');

      // Show item selected
      $('.item', $medias)
          .eq(newIndex)
          .css({'z-index':  2, 'opacity':0})
          .show()
          .animate({opacity: 1}, 700, 'easeInQuad')
          .addClass('current');
    }
  },

  Image : {
    init: function() {
      var $imageGallery = $('section.image-gallery');
      $imageGallery.each(function() {
        $("a[rel='image']", this).colorbox({ opacity: 0.8, current : "{current} / {total}" });
      })

    }
  }
};


var Form = {
  init: function() {
    $('form').each(function() {
      var $form = $(this),
          $errorMessage = $('<p />', {'class': 'error-message', html : 'Please ensure you fill out all fields labelled with an *'}).prependTo($form);
      $form
          .validate({
        invalidHandler:function() {
          $errorMessage.show();
        }
      });
    });
  }
};

function TwitterProfile(section) {
  var TwitterProfile = this;

  this.section = section;
  this.context = {};
  this.username = $(this.section).data('twitterUsername');

  this.fetchTweetData = function() {

    $.getJSON("http://twitter.com/statuses/user_timeline/" + this.username + ".json?callback=?", function(data) {
      var tweet = data[0];
      TwitterProfile.context.username = TwitterProfile.username;
      TwitterProfile.context.name = tweet.user.name;
      TwitterProfile.context.last_tweet = Utils.formatTweet(tweet.text);
      TwitterProfile.context.last_tweet_time = Utils.relative_time(tweet.created_at);
      TwitterProfile.context.imageUrl = tweet.user.profile_image_url;
      TwitterProfile.showTweet();
    });
  };

  this.showTweet = function() {
    var $twitterBlockInner = $(this.section).find('.twitter-profile-block-inner');

    // Create the avatar
    Handlebars.registerHelper('avatar', function() {
      var result = '<img src="' + this.imageUrl + '" alt="' + TwitterProfile.username + '" width="60" height="60">';
      return new Handlebars.SafeString(result);
    });

    Handlebars.registerHelper('last_tweet', function() {
      return new Handlebars.SafeString(this.last_tweet);
    });


    // Compile the template
    var template = Handlebars.compile($twitterBlockInner.html());

    // Fade In the content of the template compiled
    $twitterBlockInner.html((template(TwitterProfile.context)))
        .fadeIn('fast', 'easeOutExpo')
        .parent()
        .height($twitterBlockInner.height());
  };

  // get the data
  this.fetchTweetData();
  deifined

}


// Helpers fonction
var Utils = {
  formatTweet: function(text) {
    var urlRegex = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,
        userRegex = /[\@]+([A-Za-z0-9-_]+)/gi,
        hashRegex = / [\#]+([A-Za-z0-9-_]+)/gi;

    text = text.replace(urlRegex, "<a href=\"$1\">$1</a>");
    text = text.replace(userRegex, "<a class=\"tweet-user-link\" href=\"http://twitter.com/$1\"><span>@</span>$1</a>");
    text = text.replace(hashRegex, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from=flint_tweets">#$1</a>');
    return(text);
  },

  relative_time: function(time_value) {
    var parsed_date = this.parse_date(time_value);
    var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
    var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
    var pluralize = function (singular, n) {
      return '' + n + ' ' + singular + (n == 1 ? '' : 's');
    };
    if (delta < 60) {
      return 'less than a minute ago';
    } else if (delta < (60 * 60)) {
      return 'about ' + pluralize("minute", parseInt(delta / 60)) + ' ago';
    } else if (delta < (24 * 60 * 60)) {
      return 'about ' + pluralize("hour", parseInt(delta / 3600)) + ' ago';
    } else {
      return 'about ' + pluralize("day", parseInt(delta / 86400)) + ' ago';
    }
  },

  format_date: function(date_value) {
    var d = date_value.substr(0, 16),
        monthNames = new Array();
    monthNames["Jan"] = "January";
    monthNames["Feb"] = "February";
    monthNames["Mar"] = "March";
    monthNames["Apr"] = "April";
    monthNames["May"] = "May";
    monthNames["Jun"] = "June";
    monthNames["Jul"] = "July";
    monthNames["Aug"] = "August";
    monthNames["Sep"] = "September";
    monthNames["Oct"] = "October";
    monthNames["Nov"] = "November";
    monthNames["Dec"] = "December";

    date_formated = d.substr(5, 2) + ' ' + monthNames[d.substr(8, 3)] + ', ' + d.substr(12, 4);

    return (date_formated);
  },
  parse_date: function(date_str) {
    // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
    // cannot handle in IE. We therefore perform the following transformation:
    // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
    return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
  }
};













