/*!  
  Loosely based on Dojo pub/sub API
  ****Updated for jQuery consistency - Rick Waldron
*/  

;(function($){

  // PUB/SUB SYSTEM
  var _payload = {};
  
  $.extend({
    detonate: function(cord, args){
      
      //cord  = $.isArray(cord) ? cord: [cord]; 
      
      $.each(_payload[cord], function(){
      
        //console.log(cord);
        this.apply(this, args || []);
      });
    },
    charge: function(cord, callback){

      if(!_payload[cord]){
        _payload[cord] = [];
      }
      _payload[cord].push(callback);
      return [cord, callback]; // Array
    },
    deact: function(handle){
      var t = handle[0];
      $.each(_payload[t], function(index){
        if(this == handle[1]){
          _payload[t].splice(index, 1);
        }
      });
    }    
  });

  //  BLOCKS SELECTING TEXT
  if ($.browser.mozilla) {
    $.fn.blockselect = function() {
      return this.each(function() {
        $(this).css({
            'MozUserSelect' : 'none'
        });
      });
    };
    $.fn.unblockselect = function() {
      return this.each(function() {
        $(this).css({
            'MozUserSelect' : ''
        });
      });
    };
  } else if ($.browser.msie) {
    $.fn.blockselect = function() {
      return this.each(function() {
        $(this).bind('selectstart.blockselect', function() {
            return false;
        });
      });
    };
    $.fn.unblockselect = function() {
      return this.each(function() {
        $(this).unbind('selectstart.blockselect');
      });
    };
  } else {
    $.fn.blockselect = function() {
      return this.each(function() {
        $(this).bind('mousedown.blockselect', function() {
            return false;
        });
      });
    };
    $.fn.unblockselect = function() {
      return this.each(function() {
          $(this).unbind('mousedown.blockselect');
      });
    };
  }
  
  //  COOKIES
  $.extend({
    cookie: function(name, value, options) {
      if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
          value = '';
          options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
          var date;
          if (typeof options.expires == 'number') {
              date = new Date();
              date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
          } else {
              date = options.expires;
          }
          expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        
        options.domain  = '.signed-on.com';
        
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path    = options.path ? '; path=' + (options.path) : '';
        var domain  = options.domain ? '; domain=' + (options.domain) : '';
        var secure  = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');

        return true;

      } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
          var cookies = document.cookie.split(';');
          for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
          }
        }
        return cookieValue;
      }
    }
  });  

  //  ELASTIC
  $.fn.extend({elastic:function(){var mimics=['paddingTop','paddingRight','paddingBottom','paddingLeft','fontSize','lineHeight','fontFamily','width','fontWeight'];return this.each(function(){if(this.type!='textarea'){return false;}
  var $textarea=$(this),$twin=$('<div />').css({'position':'absolute','display':'none'}),lineHeight=parseInt($textarea.css('lineHeight'),10)||parseInt($textarea.css('fontSize'),'10'),minheight=parseInt($textarea.css('height'),10)||lineHeight*3,maxheight=parseInt($textarea.css('max-height'),10)||Number.MAX_VALUE,goalheight=0,i=0;$twin.appendTo($textarea.parent());var i=mimics.length;while(i--){$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));}
  function setHeightAndOverflow(height,overflow){curratedHeight=Math.floor(parseInt(height,10));if($textarea.height()!=curratedHeight){$textarea.css({'height':curratedHeight+'px','overflow':overflow});}}
  function update(){var textareaContent=$textarea.val().replace(/<|>/g,' ').replace(/\n/g,'<br />').replace(/&/g,"&amp;");var twinContent=$twin.html();if(textareaContent+'&nbsp;'!=twinContent){$twin.html(textareaContent+'&nbsp;');if(Math.abs($twin.height()+lineHeight-$textarea.height())>3){var goalheight=$twin.height()+lineHeight;if(goalheight>=maxheight){setHeightAndOverflow(maxheight,'auto');}else if(goalheight<=minheight){setHeightAndOverflow(minheight,'hidden');}else{setHeightAndOverflow(goalheight,'hidden');}}}}
  $textarea.css({'overflow':'hidden'}).bind('focus',function(){self.periodicalUpdater=window.setInterval(function(){update();},50);}).bind('blur',function(){clearInterval(self.periodicalUpdater);});update();});}});



  $.uniform = {
    options: {
      selectClass:   'selector',
      radioClass: 'radio',
      checkboxClass: 'checker',
      fileClass: 'uploader',
      filenameClass: 'filename',
      fileBtnClass: 'action',
      fileDefaultText: 'No file selected',
      fileBtnText: 'Choose File',
      checkedClass: 'checked',
      focusClass: 'focus',
      disabledClass: 'disabled',
      activeClass: 'active',
      hoverClass: 'hover',
      useID: true,
      idPrefix: 'uniform',
      resetSelector: false
    },
    elements: []
  };

  if($.browser.msie && $.browser.version < 7){
    $.support.selectOpacity = false;
  }else{
    $.support.selectOpacity = true;
  }

  $.fn.uniform = function(options) {
    
    options = $.extend($.uniform.options, options);

    var el = this;
    //code for specifying a reset button
    if(options.resetSelector != false){
      $(options.resetSelector).mouseup(function(){
        function resetThis(){
          $.uniform.update(el);
        }
        setTimeout(resetThis, 10);
      });
    }

    function doSelect(elem){

      var divTag = $('<div />'),
          spanTag = $('<span />');

      divTag.addClass(options.selectClass);

      if(options.useID){
        divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
      }
      
      var selected = elem.find(":selected:first");
      if(selected.length == 0){
        selected = elem.find("option:first");
      }
      spanTag.html(selected.text());
      
      elem.css('opacity', 0);
      elem.wrap(divTag);
      elem.before(spanTag);

      //redefine variables
      divTag = elem.parent("div");
      spanTag = elem.siblings("span");

      elem.change(function() {
        spanTag.text(elem.find(":selected").text());
        divTag.removeClass(options.activeClass);
      })
      .focus(function() {
        divTag.addClass(options.focusClass);
      })
      .blur(function() {
        divTag.removeClass(options.focusClass);
        divTag.removeClass(options.activeClass);
      })
      .mousedown(function() {
        divTag.addClass(options.activeClass);
      })
      .mouseup(function() {
        divTag.removeClass(options.activeClass);
      })
      .click(function(){
        divTag.removeClass(options.activeClass);
      })
      .hover(function() {
        divTag.addClass(options.hoverClass);
      }, function() {
        divTag.removeClass(options.hoverClass);
      })
      .keyup(function(){
        spanTag.text(elem.find(":selected").text());
      });

      //handle disabled state
      if($(elem).attr("disabled")){
        //box is checked by default, check our box
        divTag.addClass(options.disabledClass);
      }
      $.uniform.noSelect(spanTag);
      
      storeElement(elem);

    }

    function doCheckbox(elem){

      var divTag = $('<div />'),
          spanTag = $('<span />');

      divTag.addClass(options.checkboxClass);

      //assign the id of the element
      if(options.useID){
        divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
      }

      //wrap with the proper elements
      $(elem).wrap(divTag);
      $(elem).wrap(spanTag);

      //redefine variables
      spanTag = elem.parent();
      divTag = spanTag.parent();

      //hide normal input and add focus classes
      $(elem)
      .css("opacity", 0)
      .focus(function(){

        divTag.addClass(options.focusClass);
      })
      .blur(function(){

        divTag.removeClass(options.focusClass);
      })
      .click(function(){

        if(!$(elem).attr("checked")){
          //box was just unchecked, uncheck span
          spanTag.removeClass(options.checkedClass);
        }else{
          //box was just checked, check span.
          spanTag.addClass(options.checkedClass);
        }
      })
      .mousedown(function() {
        divTag.addClass(options.activeClass);
      })
      .mouseup(function() {
        divTag.removeClass(options.activeClass);
      })
      .hover(function() {
        divTag.addClass(options.hoverClass);
      }, function() {
        divTag.removeClass(options.hoverClass);
      });

      //handle defaults
      if($(elem).attr("checked")){
        //box is checked by default, check our box
        spanTag.addClass(options.checkedClass);
      }

      //handle disabled state
      if($(elem).attr("disabled")){
        //box is checked by default, check our box
        divTag.addClass(options.disabledClass);
      }

      storeElement(elem);

    }

    function doRadio(elem){

      var divTag = $('<div />'),
          spanTag = $('<span />');

      divTag.addClass(options.radioClass);

      if(options.useID){
        divTag.attr("id", options.idPrefix+"-"+elem.attr("id"));
      }

      //wrap with the proper elements
      $(elem).wrap(divTag);
      $(elem).wrap(spanTag);

      //redefine variables
      spanTag = elem.parent();
      divTag = spanTag.parent();

      //hide normal input and add focus classes
      $(elem)
      .css("opacity", 0)
      .focus(function(){
        divTag.addClass(options.focusClass);
      })
      .blur(function(){
        divTag.removeClass(options.focusClass);
      })
      .click(function(){
        if(!$(elem).attr("checked")){
          //box was just unchecked, uncheck span
          spanTag.removeClass(options.checkedClass);
        }else{
          //box was just checked, check span
          $("."+options.radioClass + " span."+options.checkedClass + ":has([name='" + $(elem).attr('name') + "'])").removeClass(options.checkedClass);
          spanTag.addClass(options.checkedClass);
        }
      })
      .mousedown(function() {
        if(!$(elem).is(":disabled")){
          divTag.addClass(options.activeClass);
        }
      })
      .mouseup(function() {
        divTag.removeClass(options.activeClass);
      })
      .hover(function() {
        divTag.addClass(options.hoverClass);
      }, function() {
        divTag.removeClass(options.hoverClass);
      });

      //handle defaults
      if($(elem).attr("checked")){
        //box is checked by default, check span
        spanTag.addClass(options.checkedClass);
      }
      //handle disabled state
      if($(elem).attr("disabled")){
        //box is checked by default, check our box
        divTag.addClass(options.disabledClass);
      }

      storeElement(elem);

    }

    function doFile(elem){
      //sanitize input
      $el = $(elem);

      var divTag = $('<div />'),
          filenameTag = $('<span>'+options.fileDefaultText+'</span>'),
          btnTag = $('<span>'+options.fileBtnText+'</span>');

      divTag.addClass(options.fileClass);
      filenameTag.addClass(options.filenameClass);
      btnTag.addClass(options.fileBtnClass);

      if(options.useID){
        divTag.attr("id", options.idPrefix+"-"+$el.attr("id"));
      }

      //wrap with the proper elements
      $el.wrap(divTag);
      $el.after(btnTag);
      $el.after(filenameTag);

      //redefine variables
      divTag = $el.closest("div");
      filenameTag = $el.siblings("."+options.filenameClass);
      btnTag = $el.siblings("."+options.fileBtnClass);

      //set the size
      if(!$el.attr("size")){
        var divWidth = divTag.width();
        //$el.css("width", divWidth);
        $el.attr("size", divWidth/10);
      }

      //actions
      $el
      .css("opacity", 0)
      .focus(function(){
        divTag.addClass(options.focusClass);
      })
      .blur(function(){
        divTag.removeClass(options.focusClass);
      })
      .change(function(){
        var filename = $(this).val();
        filename = filename.split(/[\/\\]+/);
        filename = filename[(filename.length-1)];
        filenameTag.text(filename);
      })
      .mousedown(function() {
        if(!$(elem).is(":disabled")){
          divTag.addClass(options.activeClass);
        }
      })
      .mouseup(function() {
        divTag.removeClass(options.activeClass);
      })
      .hover(function() {
        divTag.addClass(options.hoverClass);
      }, function() {
        divTag.removeClass(options.hoverClass);
      });

      //handle defaults
      if($el.attr("disabled")){
        //box is checked by default, check our box
        divTag.addClass(options.disabledClass);
      }
      
      $.uniform.noSelect(filenameTag);
      $.uniform.noSelect(btnTag);
      storeElement(elem);

    }

    function storeElement(elem){
      //store this element in our global array
      elem = $(elem).get();
      if(elem.length > 1){
        $.each(elem, function(i, val){
          $.uniform.elements.push(val);
        });
      }else{
        $.uniform.elements.push(elem);
      }
    }
    
    //noSelect v1.0
    $.uniform.noSelect = function(elem) {
      function f() {
       return false;
      };
      $(elem).each(function() {
       this.onselectstart = this.ondragstart = f; // Webkit & IE
       $(this)
        .mousedown(f) // Webkit & Opera
        .css({ MozUserSelect: 'none' }); // Firefox
      });
     };

    $.uniform.update = function(elem){
      if(elem == undefined){
        elem = $($.uniform.elements);
      }
      //sanitize input
      elem = $(elem);

      elem.each(function(){
        //do to each item in the selector
        //function to reset all classes
        $e = $(this);

        if($e.is("select")){
          //element is a select
          spanTag = $e.siblings("span");
          divTag = $e.parent("div");

          divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);

          //reset current selected text
          spanTag.html($e.find(":selected").text());

          if($e.is(":disabled")){
            divTag.addClass(options.disabledClass);
          }else{
            divTag.removeClass(options.disabledClass);
          }

        }else if($e.is(":checkbox")){
          //element is a checkbox
          spanTag = $e.closest("span");
          divTag = $e.closest("div");

          divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
          spanTag.removeClass(options.checkedClass);

          if($e.is(":checked")){
            spanTag.addClass(options.checkedClass);
          }
          if($e.is(":disabled")){
            divTag.addClass(options.disabledClass);
          }else{
            divTag.removeClass(options.disabledClass);
          }

        }else if($e.is(":radio")){
          //element is a radio
          spanTag = $e.closest("span");
          divTag = $e.closest("div");

          divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);
          spanTag.removeClass(options.checkedClass);

          if($e.is(":checked")){
            spanTag.addClass(options.checkedClass);
          }

          if($e.is(":disabled")){
            divTag.addClass(options.disabledClass);
          }else{
            divTag.removeClass(options.disabledClass);
          }
        }else if($e.is(":file")){
          divTag = $e.parent("div");
          filenameTag = $e.siblings(options.filenameClass);
          btnTag = $e.siblings(options.fileBtnClass);

          divTag.removeClass(options.hoverClass+" "+options.focusClass+" "+options.activeClass);

          filenameTag.text($e.val());

          if($e.is(":disabled")){
            divTag.addClass(options.disabledClass);
          }else{
            divTag.removeClass(options.disabledClass);
          }
        }
      });
    }

    return this.each(function() {
      if($.support.selectOpacity){
        var elem = $(this);

        if(elem.is("select")){
          //element is a select
          if(elem.attr("multiple") != true){
            //element is not a multi-select
            doSelect(elem);
          }
        }else if(elem.is(":checkbox")){
          //element is a checkbox
          doCheckbox(elem);
        }else if(elem.is(":radio")){
          //element is a radio
          doRadio(elem);
        }else if(elem.is(":file")){
          //element is a file upload
          doFile(elem);
        }

      }
    });
  };




  $.fn.dimensions = function () {
    return this.each(function () {
      var _dims = {
        width: $(this).width(),
        height: $(this).height()
      };
      return _dims;
    });
  };


  $.fn.iframeResize = function(options){
    var settings = $.extend({
      width: "fill",
      height: "auto",
      autoUpdate : true
    }, options);
    var filler = 30;

    function onEachIframe(){
      var frame = $(this);
      var body = frame.contents().find("body");

      frame.css("overflow", "hidden");
      if (settings.autoUpdate) {
        if ($.browser.msie) {
          frame.attr("scrolling", "auto");
          setInterval(immediateResize, 1000);
        }
        else {
          body.bind("DOMSubtreeModified", {
            frame: frame
          }, resizeIframe);
        }
      }
      immediateResize();

      function immediateResize(){
        var e = $.Event();
        e.data = {};
        e.data.frame = frame;
        resizeIframe.call(body, e);
      }
    }

    function resizeIframe(event){
      var body = $(this);
      event.data.frame.css("width",  settings.width  == "fill" ? "100%" : parseInt(settings.height));
      event.data.frame.css("height", settings.height == "auto" ? body.outerHeight(true) + filler : parseInt(settings.height));
    }

    $(this).children("iframe").each(onEachIframe);
  };




//  END PLUGINS
})(jQuery);


