//  main.js                                              Copyright (C) 2010-11 Do Good Lab. All Rights Reserved.
//
//  This code is provided to you pursuant to the terms and conditions set forth in the  evaluation  license  (or
//  subsequent license agreement) between your organization and Do Good Lab.
//
//  Author(s): Thomas Jansen (thomas.c.jansen@gmail.com)


// ---[ CONSTANTS ]---------------------------------------------------------------------------------------------

var COVER_SHOW_TIME     = 8000;                                           //      Show each cover for 8 seconds.
var COVER_FADE_TIME     =  600;                                           //    Fade between covers in 600 msec.


// ---[ GLOBAL VARIABLES ]--------------------------------------------------------------------------------------

var coverFadeTimeoutID  = null;                                           //          Used for the cover fading.


// ---[ EXTEND JQUERY ]-----------------------------------------------------------------------------------------

/*
    Compare two jQuery elements.
*/
$.fn.equals = function(element)
{
  return ($(this).get(0) == element.get(0));
};


// ---[ INITIALIZE ]--------------------------------------------------------------------------------------------

/*
    Is called when document is done with loading.
*/
$(document).ready(function()
{
  // 1: be compatible with ie6...
  fixIE6();

  // 2: initialize default texts...
  $('input.text').each(function()
  {
    // 2.1: only if we have a title...
    if($(this).attr('title').length > 0)
    {
      // 2.1.1: get focus...
      $(this).focus(function()
      {
        if($(this).hasClass('empty'))
        {
          $(this).removeClass('empty');
          $(this).val('');
        }
      });

      // 2.1.2: lose focus...
      $(this).blur(function()
      {
        if(($(this).val().length == 0) || ($(this).val() == $(this).attr('title')))
        {
          $(this).addClass('empty');
          $(this).val($(this).attr('title'));
        }
      });

      // 2.1.3: initialize...
      $(this).blur();
    }
  });

  // 3: make widget headlines clickable...
  $('#widget h1').each(function()
  {
    // 3.1: gather information..
    var href = $(this).parents('#widget').find('a:last').attr('href');
    var text = $(this).text();

    // 3.2: make the header clickable...
    if(href && (href.length > 0) && text && (text.length > 0))
      $(this).html('<a href="' + href + '" title="' + text + '">' + text + '</a>');
  });

  // 4: cover story events...
  $('div#cover_shortcuts a.shortcut').click(function(event)
  {
    coverFadeInSpecific($($(this).attr('href')));
    event.preventDefault();
  });

  $('div#cover_shortcuts a.shortcut').hover(function() { $(this).find('div').fadeIn(150); },
                                            function() { $(this).find('div').fadeOut(150); });

  // 5: initialize options...
  $('ul#options li').each(function()
  {
    $(this).mouseenter(showOption);
  });

  $('ul#options li:first').each(showOption);

  // 6: contact form was submitted...
  $('#mailinglist-subscribe .button').click(handleListSubscribe);
  $('#contact-form .button').click(handleContactSubmit);

  // 7: load tweets...
  $('#tweets').each(function()
                    {
                      $.ajax( { url: 'http://search.twitter.com/search.json?callback=?',
                           dataType: 'json',
                               data: { q: 'from:DoGoodLab', rpp: 5 },
                            success: tweetsLoaded,
                            context: this } );
                    });
  
  // 8: start fading...
  coverStartFading();
});


// ---[ COVER FUNCTIONS ]---------------------------------------------------------------------------------------

/*!
    Start the fading.
*/
function coverStartFading()
{
  // 1: show first cover...
  $('.cover:last').show();
  
  // 2: and wait until it is completely loaded...
  ensureImageLoaded($('.cover:last img'),
                    function()
                    {
                      $('.cover').show();
                      
                      if(coverFadeTimeoutID === null)
                        coverFadeTimeoutID = window.setTimeout(coverFadeInNext, COVER_SHOW_TIME);
                    });
}


/*
    Fade in next cover.
*/
function coverFadeInNext()
{
  // 1: fade in the one before the last...
  coverFadeInSpecific($('.cover:last').prev('.cover'));
}


/*
    Fade in specific.
*/
function coverFadeInSpecific(next_cover)
{
  // 1: stop old timer if needed...
  if(coverFadeTimeoutID !== null)
  {
    window.clearTimeout(coverFadeTimeoutID);
    coverFadeTimeoutID = null;
  }
  
  // 2: find current cover...
  var current_cover = $('.cover:last');
  if(current_cover.equals(next_cover))
  {
    // 2.1: just restart the timer...
    coverFadeTimeoutID = window.setTimeout(coverFadeInNext, COVER_SHOW_TIME);
    return;
  }
  
  // 3: hide all covers between the current and the next one...
  var previous_cover = current_cover.prev('.cover');
  
  while((previous_cover.length > 0) && (!previous_cover.equals(next_cover)))
  {
    previous_cover.hide();
    previous_cover = previous_cover.prev('.cover');
  }
  // 4: and fade out the top one (as soon as the new image is fully loaded)...
  
  ensureImageLoaded(next_cover.find('img'),
                    function()
                    {
                      current_cover.fadeOut(COVER_FADE_TIME, coverMoveNextToTop);
                    });
}


/*
    Bring top cover to back and restart timer.
*/
function coverMoveNextToTop()
{
  // 1: get old top cover and it's parent...
  var current_top = $('.cover:last');
  var parent      = current_top.parent();
  
  // 2: move all invisible covers to bottom...
  while(current_top.is(':hidden'))
  {
    parent.prepend(current_top.detach());
    current_top.show();
    
    current_top = parent.find('.cover:last');
  }

  // 3: restart timer...
  if(coverFadeTimeoutID === null)
    coverFadeTimeoutID = window.setTimeout(coverFadeInNext, COVER_SHOW_TIME);
}


/*
    Ensure that an image is loaded before calling the callback.
*/
function ensureImageLoaded(elements, callback)
{
  // 1: is image already loaded?
  if((elements.length == 0) || (elements.get(0).complete))
    callback();
  else
    elements.load(callback);
}


// ---[ FORM FUNCTIONS ]----------------------------------------------------------------------------------------

/*
    ...
*/
function handleListSubscribe(event)
{
  event.preventDefault();

  // 1: is button disabled?
  if($(this).hasClass('disabled'))
    return;
  
  // 2: extract email address...
  var address = $('#mailinglist-subscribe input[id=email]').hasClass('empty') ? ''
                                                                              : $('#mailinglist-subscribe input[id=email]').val() || '';
  if(!validateEmail(address))
  {
    $('#mailinglist-subscribe input[id=email]').addClass('bad').focus();
    return;
  }

  $('#mailinglist-subscribe input[id=email]').removeClass('bad');
  
  // 3: everything is fine, send it to the server...
  var url = $("#theme_path").attr("content") + '/ajax/subscribe.php';

  $.ajax( {      url: url,
                data: { address: address },
            dataType: 'json',
                type: 'post',
             success: function(data)
                      {
                        // 4.1: received data...

                        if(data && (data['result'] == 'success'))
                        {
                          // 4.1.1: and was successful...

                          $('#mailinglist-subscribe input[id=email]').val('Subscription successful');

                          $('#mailinglist-subscribe input[id=email]').attr('disabled', 'disabled').addClass('success');
                          $('#mailinglist-subscribe .button'        ).attr('disabled', 'disabled').addClass('success');
                        }
                        else
                        {
                          // 4.1.2: but was failure...

                          $('#mailinglist-subscribe input[id=email]').val('Subscription failed!');

                          $('#mailinglist-subscribe input[id=email]').attr('disabled', 'disabled').addClass('failure');
                          $('#mailinglist-subscribe .button'        ).attr('disabled', 'disabled').addClass('failure');
                        }
                      },
               error: function()
                      {
                        // 4.2: failed receiving data...
         
                        $('#mailinglist-subscribe input[id=email]').val('Subscription failed!');

                        $('#mailinglist-subscribe input[id=email]').attr('disabled', 'disabled').addClass('failure');
                        $('#mailinglist-subscribe .button'        ).attr('disabled', 'disabled').addClass('failure');
                      }
          } );
}


/*
    Contact form was submitted.
*/
function handleContactSubmit(event)
{
  event.preventDefault();

  // 1: is button disabled?
  if($(this).hasClass('disabled'))
    return;
  
  // 2: validate everything...
  var first_failed = null;

    // 2.1: name...
    var name = $('#contact-form input[id=name]').hasClass('empty')? '' : $('#contact-form input[id=name]').val() || '';

    // 2.2: email...
    var email = $('#contact-form input[id=email]').hasClass('empty')? '' : $('#contact-form input[id=email]').val() || '';
    if(!validateEmail(email))
    {
      $('#contact-form div#email').addClass('bad');
      first_failed = first_failed || $('#contact-form input[id=email]');
    }
    else
    {
      $('#contact-form div#email').removeClass('bad');
    }

    // 2.3: subject...
    var subject = $('#contact-form input[id=subject]').hasClass('empty')? '' : $('#contact-form input[id=subject]').val() || '';
  
    // 2.4: message...
    var message = $('#contact-form textarea[id=message]').val() || '';
    if(message.length == 0)
    {
      $('#contact-form div#message').addClass('bad');
      first_failed = first_failed || $('#contact-form textarea[id=message]');
    }
    else
    {
      $('#contact-form div#message').removeClass('bad');
    }
  
  // 3: did something fail?
  if(first_failed)
  {
    first_failed.focus();
    return;
  }
  
  // 4: everything is fine, send it to the server...
  var url = $("#theme_path").attr("content") + '/ajax/contact.php';
  
  $.ajax( {      url: url,
                data: {    name: name,
                          email: email,
                        subject: subject,
                        message: message },
            dataType: 'json',
                type: 'post',
             success: function(data)
                      {
                        // 4.1: received data...
                        if(data && (data['result'] == 'success'))
                        {
                          // 4.1.1: and was successful...
                          $('#contact-form span#success').show();
                          $('#contact-form span#failure').hide();
         
                          $('#contact-form input[id=name]'      ).attr('disabled', 'disabled').addClass('disabled');
                          $('#contact-form input[id=email]'     ).attr('disabled', 'disabled').addClass('disabled');
                          $('#contact-form input[id=subject]'   ).attr('disabled', 'disabled').addClass('disabled');
                          $('#contact-form textarea[id=message]').attr('disabled', 'disabled').addClass('disabled');
                          $('#contact-form #submit'             ).attr('disabled', 'disabled').addClass('disabled');
                        }
                        else
                        {
                          // 4.1.2: but was failure...
                          $('#contact-form span#success').hide();
                          $('#contact-form span#failure').show();
                        }
                      },
               error: function()
                      {
                        // 4.2: failed receiving data...
                        $('#contact-form span#success').hide();
                        $('#contact-form span#failure').show();
                      }
          } );
}


// ---[ OPTIONS ]-----------------------------------------------------------------------------------------------

/*
    An option was clicked.
*/
function showOption()
{
  // 1: check if already shown...
  var new_option = $('div.option#' + $(this).attr('id'));

  if(new_option.is(':visible'))
    return;

  // 2: hide all option items, except the hovered...
  $(this).siblings('li').animate({ opacity: 0.5 }, {duration: 200, queue: false });

  $(this).animate({ opacity: 1.0 }, {duration: 200, queue: false });

  // 3: hide all option sheets, except for the hovered...
  $('div.option').hide();

  new_option.show().css({ opacity: 0.0, top: 12 })
                   .animate({ opacity: 1.0, top: 0 }, {duration: 200, queue: false });
}


// ---[ TWITTER ]-----------------------------------------------------------------------------------------------

/*
    Tweets successfully loaded.
*/
function tweetsLoaded(data)
{
  // 1: do we have results...
  if(!data.results)
    return;
    
  // 2: traverse through all results...
  var tweets = [];
  for(var i in data.results)
  {
    // 2.1: do we have some text...
    if(!data.results[i].text)
      continue;
      
    // 2.3: create twitter text...
    var text = 	data.results[i].text.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g,
                                             function(url)
                                             {
                                           		 return '<a href="' + url + '" target="_blank">' +
                                           		          url +
                                           		        '</a>';
	                                           })
                                    .replace(/[@]+[A-Za-z0-9-_]+/g,
                                             function(user)
                                             {
                                           		 return '<a href="http://twitter.com/' + user.replace("@","") + '" target="_blank">' +
                                           		          user +
                                           		        '</a>';
	                                           })
                                    .replace(/[#]+[A-Za-z0-9-_]+/g,
                                             function(tag)
                                             {
                                           		 return '<a href="http://search.twitter.com/search?q=' + tag.replace("#","%23") + '" target="_blank">' +
                                           		          tag +
                                           		        '</a>';
		                                         });

    // 2.2: append text...
    tweets.push(text);
    
    if(tweets.length == 2)
      break;
  }
  
  // 3: insert the html...
  $(this).html('<ul class="tweetList">' +
                 '<li>' +
                   '<p>' +
                     tweets.join('</p></li><li><p>') +
                   '</p>' +
                 '</li>' +
               '</ul>');
  
  // 4: install handler...
  $(this).find('.tweetList li p').hover(tweetStartScroll,
                                        tweetStopScroll);
  
  // 5: fade in...
  $(this).css    ( { opacity: 0.0 } )
         .animate( { opacity: 1.0 } );
}


/*
    A tweet starts to scroll.
*/
function tweetStartScroll()
{
  // 1: by how many pixels do we have to move?
  var distance = Math.max(0, $(this).height() - $(this).parent().height());

  // 2: program the animation...
  $(this).animate( { 'top':         0 },          1000 )
         .animate( { 'top': -distance }, 60 * distance )
         .animate( { 'top': -distance },          2000 )
         .animate( { 'top':         0 }, 60 * distance )
         .animate( { 'top':         0 },          1000, tweetStartScroll );
}


/*
    A tweet stops to scroll.
*/
function tweetStopScroll()
{
  $(this).stop(true)
         .css( { 'top' : 0 } );
}


// ---[ TOOLS ]-------------------------------------------------------------------------------------------------

/*
    Validate an Email address.
*/
function validateEmail(email)
{
  // 1: this is not perfect...
  return email.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
}


/*
    Fix some problems with IE6.
*/
function fixIE6()
{
  // 1: are we running in IE6?
  if($("#is_ie6").length == 0)
    return;

  // 2: special treatment of some links...
  $("a.fancy[href$='.pdf']").addClass('pdf');
  $("a.fancy[href$='.doc']").addClass('doc');

  // 3: make transparent PNGs work...
  DD_belatedPNG.fix('div#logo, ' +
                    '#header #links a, ' +
                    '.hr, ' +
                    '#widget li#facebook, #widget li#feed, ' +
                    '#mailinglist-subscribe, ' +
                    '#contact-form span.label.required, ' +
                    'a.pdf, ' +
                    '#contact-form span#success, ' +
                    '#contact-form span#failure, ' +
                    'input#button, ' +
                    'ul#options li, ' +
                    'div.option' +
                    'div.active_page' +
                    'div.inactive_page');
}

