/***********************************************************
 *
 *  File:       main.js
 *  Author:     Andy dePasquale
 *  Created:    May 2010
 *
 *  Description:
 *  Utility functions used throughout site, assumes
 *  the inclusion of JQuery
 *
 **********************************************************/

function inspect(obj) {
  var str = '';
  for (var i in obj) str += i + ': ' + obj[i] + '\n';
  alert(str);
}

var _isIE6 = false; //explicit browser detection for conditional blocks

$(document).ready(function(){
  
  /* test js log - remove for production */
  if (jsLogOn) $('#body').append('<ul id="jsOutput"></ul>');
  /* end test js log */

	//===============================================
	//	PORTFOLIO
	//===============================================
  (function($){
    $.fn.portfolio = function(options) {
      return this.each(function() {
        new $pf(this, options);
      });
    };
    
    var defaults = {
      //offsets
      ttTop: 30,
      ttLeft: 15,
      //animation
      fOut: fadeDuration(150),
      fIn: fadeDuration(600),
      easing: 'easeOutQuint'
    };
    
    /**
     * The portfolio object.
     *
     * @constructor
     * @name $.portfolio
     * @param Object e The element to create the portfolio for.
     * @param Hash o A set of key/value pairs to set as configuration properties.
     */
    $.portfolio = function(e, o) {
      this.options            = $.extend({}, defaults, o || {});

      //elements
      var self                = this;
      this.container          = $(e);
      this.tns                = this.container.find('li a');
      this.ulCont             = $(this.container.parent());
      //add tooltip
      var tipHtml = '<div id="tooltip" class="tooltip"><div class="tip-pt"></div><div class="tip-top"></div><div id="tooltipInner" class="tip"></div><div class="tip-btm"></div></div>';
      $(tipHtml).appendTo(this.ulCont);
      this.tt                 = $('#tooltip');
      this.tti                = $('#tooltipInner');
      this.fadeID             = null;
      
      //attach behavior & tooltip-related data
      this.tns.each(function(){
        //save position data
        var pos = $(this).parent().position();
        $(this).data('pos', {
          'left': pos.left + self.options.ttLeft,
          'top':  pos.top + self.options.ttTop,
          'text': $(this).attr('title')
        });
        $(this).attr('title','');
        //click
        $(this).bind('click', function(e){
          if (!$(this).hasClass('sel')) self.fetch($(this).attr('rel'), self);
          $(self.container).find('li a.sel').removeClass('sel');
          $(this).addClass('sel');
          e.preventDefault();
        }).bind('mouseenter', function(e){
          self.moveTooltip($(this));
        }).bind('mouseleave', function(e){
          $(self.tt).fadeOut(self.options.fOut);
        });
      });
      
/*
      this.tns.each(function(){
        //tooltip
        var tipHtml = '<div class="tooltip"><div class="tip-pt"></div><div class="tip-top"></div><div class="tip">' + $(this).attr('title') + '</div><div class="tip-btm"></div></div>';
        $(tipHtml).appendTo($(this));
        $(this).attr('title','').data('tip', $(this).find('.tooltip'));
        //click
        $(this).bind('click', function(e){
          if (!$(this).hasClass('sel')) self.fetch($(this).attr('rel'), self);
          $(self.container).find('li a.sel').removeClass('sel');
          $(this).addClass('sel');
          e.preventDefault();
        }).bind('mouseenter', function(e){
          $(this).siblings().find('.tooltip').hide();
          $(this).data('tip').fadeIn(self.options.dur);
        }).bind('mouseleave', function(e){
          $(this).data('tip').fadeOut(100);
        });
      });
*/

    };

    // Create shortcut for internal use
    var $pf = $.portfolio;
    $pf.fn = $pf.prototype = {};
    $pf.fn.extend = $pf.extend = $.extend;

    $pf.fn.extend({
      /**
       * Fetches selected portfolio item.
       *
       * @name fetch
       * @type undefined
       */
      fetch: function(id, pfObj) {
        var o = pfObj;
        var n = parseInt(id.replace(/$tn([0-9]+)/,'$1'));
        jQuery.getJSON(
          'ajax/load_clients.php?cID=' + n,
          function(json) {
            if (!json.length) return;
            var d = json[0];
            
            o.updateInfo($('#clientName'), d.client_name);
            o.updateInfo($('#clientLoc'), d.loc);
//            o.updateInfo($('#clientAbstract'), d.abstract.replace(/\n/gi, '<br />'));
            o.updateInfo($('#clientAbstract'), d.abstract.replace(/\n/gi, '<br />'));
            o.updateUrl(d.url);
            o.updateImg(n);
          },
          'json'
        );
      },
      
      /**
       * Updates info for selected portfolio item.
       *
       * @name updateInfo
       * @type undefined
       */
      updateInfo: function(el, data) {
        var obj = this;
        $(el).animate(
          {opacity: 0},
          this.options.dur,
          this.options.easing,
          function(){
            $(el).html(data)
              .animate(
                {opacity: 1},
                obj.options.dur,
                obj.options.easing
              );
          }
        );
      },
      
      /**
       * Updates URL for selected portfolio item.
       *
       * @name updateUrl
       * @type undefined
       */
      updateUrl: function(url) {
        var obj = this;
        var el = $('#clientURL');
        if (el.hasClass('hidden')) {
          if (!url) return;
          el.attr('href', url)
            .removeClass('invisible')
            .animate(
              {opacity: 1},
              this.options.dur,
              this.options.easing,
              function(){ el.removeClass('hidden'); }
            );
        } else {
          if (!url) {
            el.animate(
              {opacity: 0},
              this.options.dur,
              this.options.easing,
              function(){ el.addClass('hidden invisible'); }
            );
          } else {
            el.attr('href', url);
          }
        }
      },
      
      /**
       * Updates image for selected portfolio item.
       *
       * @name updateImg
       * @type undefined
       */
      updateImg: function(id) {
        var el = $('#client' + id);
        var showing = $('.imgFeaturedClient:visible').css({'z-index':1});
        el.css('z-index', 10)
          .fadeIn(
            this.options.dur,
            function(){ $(showing).hide(); }
          );
      },
      
      /**
       * Updates the text and position of the tooltip.
       *
       * @name moveTooltip
       * @type undefined
       */
      moveTooltip: function(link) {
        var o = link.data('pos');
        var self = this;
        this.tt.stop(true,true)
          .fadeOut(this.options.fOut, function(){
            $(this).css({left:o.left, top:o.top});
            self.tti.html(o.text);
            $(this).fadeIn(self.options.fIn, function(){
              window.clearTimeout(self.fadeID);
              self.fadeID = window.setTimeout(function(){ self.fadeTooltip(); }, 3000);
            });
          });
      },
      
      /**
       * Fades the tooltip.
       *
       * @name fadeTooltip
       * @type undefined
       */
      fadeTooltip: function(e) {
        var self = this;
        this.tt.fadeOut(this.options.fOut, function(){
          window.clearTimeout(self.fadeID);
        });
      }
    });

  })(jQuery);
  
  $('#tnList').portfolio();

	//===============================================
	//	EMAIL FORM
	//===============================================
  (function($){
    $.fn.sendemail = function(options) {
      return this.each(function() {
        new $se(this, options);
      });
    };

    var defaults = {
      //animation
      dur: fadeDuration(600),
      easing: 'easeOutQuint'
    };

    /**
     * The sendemail object.
     *
     * @constructor
     * @name $.sendemail
     * @param Object e The element to create the sendemail object for.
     * @param Hash o A set of key/value pairs to set as configuration properties.
     */
    $.sendemail = function(e, o) {
      this.options            = $.extend({}, defaults, o || {});

      //elements
      var self                = this;
      this.container          = $(e);
      this.f                  = $('#sendEmailForm');
      this.responseMsg        = $('#responseMsg');
      this.fadeID             = null;
      
      //attach behavior to links
      $('a.email').click(function(e){
        self.container.fadeIn(self.options.dur);
        e.preventDefault();
      });
      $('#eSubmit').click(function(e){
        self.send();
        e.preventDefault();
      });
      $('#eCancel').click(function(e){
        self.fadeModal();
        e.preventDefault();
      });
      
      //validation
      this.fields             = [$('#eName'), $('#eEmail'), $('#eSubject'), $('#eMsg')];
      this.errorClass         = 'error';
    };

    // Create shortcut for internal use
    var $se = $.sendemail;
    $se.fn = $se.prototype = {};
    $se.fn.extend = $se.extend = $.extend;

    $se.fn.extend({
      /**
       * Hides the modal form.
       *
       * @name fadeModal
       * @type undefined
       */
      fadeModal: function() {
        var self = this;
        this.container.fadeOut(this.options.dur, function(){
          $(this).find('input').val('').closest('.fItem').removeClass(self.errorClass);
          $(this).find('textarea').html('').closest('.fItem').removeClass(self.errorClass);
          self.responseMsg.hide();
          self.f.show();
          window.clearTimeout(self.fadeID);
        });
      },

      /**
       * Validates the form.
       *
       * @name validate
       * @type undefined
       */
      validate: function() {
        var self = this;
        var errors = 0;
        $.each(this.fields, function(){
          if (!this.val().replace(/^\s+|\s+$/g,"")) {
            this.closest('.fItem').addClass(self.errorClass);
            errors++;
          } else {
            //valid email?
            var re = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+[a-zA-Z0-9]{2,4}$/;
            if (this.attr('id')=='eEmail' && !re.test(this.val())) {
              this.closest('.fItem').addClass(self.errorClass);
              errors++;
            } else {
              this.closest('.fItem').removeClass(self.errorClass);
            }
          }
        });
        return errors==0;
      },

      /**
       * Sends the email.
       *
       * @name send
       * @type undefined
       */
      send: function() {
        if (!this.validate()) return;
        var self = this;
        $.post(
          'ajax/send_email.php',
          this.f.serialize(),
          function() {
            self.f.hide();
            self.responseMsg.html('Your message has been sent.').show();
            self.fadeID = window.setTimeout(function(){ self.fadeModal(); }, 2000);
          }
        );
      }
    });

  })(jQuery);

  $('#sendEmail').sendemail();

	//===============================================
	//	VOID LINKS (HREF="#")
	//===============================================
	$(function(){
		$('body').click(function(e){
			var clicked = $(e.target);
			if ((clicked.get(0).tagName.toLowerCase() != 'a') && (clicked.parents('a').length)) clicked = clicked.parents('a').get(0);
			if ((typeof clicked) != 'undefined' && $(clicked).attr('href') == '#') e.preventDefault();
		});
	});

	//===============================================
	//	EXTERNAL LINKS
	//===============================================
	$(function(){
		$('a[rel="external"]').each(function() {
			$(this).attr({
				'target': 'pac',
				'title': $(this).attr('title') + ' (opens in new window)'
			}); 
		});
	});

	//===============================================
	//	SPINNERS
	//===============================================
	(function($){
		$.fn.spinner = function(options){
			var defaults = {
  		  cls:      'spinner',      //spinner class name
  		  where:    'insertAfter',  //jQuery insertion method [insertAfter, insertBefore]
  		  callback: null            //optional callback when spinner gets shown
			};
			var opts = $.extend(defaults, options); //no overrides for now
			
			return $(this).each(function(){
			  if ($(this).next().hasClass('spinner')) return;
			  var sp = $('<div class="' + opts.cls + '"></div>')[opts.where]($(this)).hide();
			  $(this).bind('click', function(){
		      sp.show();
		    });
			});
		};
		// attach to relevant btns
		$('.addSpinner').spinner();
	})(jQuery);

});

function spinner(e) {
  var self                = this;
  this.container          = $(e);
  this.container.click( function() {
    $('#btnSpinnerCont').addClass("spinner");
  });
}

/**
 * Wrapper for setting fade durations.
 * PNGs get a black halo when faded in IE, so IE-specific js returns zero.
 */
function fadeDuration(dur) {
  return dur;
}


//===============================================
//	GLOBAL NAVIGATION
//===============================================
/*
function setupGlobalNav() {
  if (!$('ul.sf-menu').length) return;
  $('ul.sf-menu').superfish({
    speed: 50,
    pathClass: 'current',
    autoArrows: false
  });
}
*/

/* test js log - remove for production */
var jsLogOn = false;
function jslog(msg) {
  if (!jsLogOn) return false;
  $('#jsOutput').prepend('<li>' + msg + '</li>');
}
/* end test js log */
