/**
 * sprintf and vsprintf for jQuery
 * somewhat based on http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
 * 
 * Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details. 
 *
 * @license http://www.gnu.org/licenses/gpl.html 
 * @project jquery.sprintf
 */
(function($){
	var formats = {
		'%': function(val) {return '%';},
		'b': function(val) {return  parseInt(val, 10).toString(2);},
		'c': function(val) {return  String.fromCharCode(parseInt(val, 10));},
		'd': function(val) {return  parseInt(val, 10) ? parseInt(val, 10) : 0;},
		'u': function(val) {return  Math.abs(val);},
		'f': function(val, p) {return  (p > -1) ? Math.round(parseFloat(val) * Math.pow(10, p)) / Math.pow(10, p): parseFloat(val);},
		'o': function(val) {return  parseInt(val, 10).toString(8);},
		's': function(val) {return  val;},
		'x': function(val) {return  ('' + parseInt(val, 10).toString(16)).toLowerCase();},
		'X': function(val) {return  ('' + parseInt(val, 10).toString(16)).toUpperCase();}
	};

	var re = /%(?:(\d+)?(?:\.(\d+))?|\(([^)]+)\))([%bcdufosxX])/g;

	var dispatch = function(data){
		if(data.length == 1 && typeof data[0] == 'object') { //python-style printf
			data = data[0];
			return function(match, w, p, lbl, fmt, off, str) {
				return formats[fmt](data[lbl]);
			};
		} else { // regular, somewhat incomplete, printf
			var idx = 0; // oh, the beauty of closures :D
			return function(match, w, p, lbl, fmt, off, str) {
				return formats[fmt](data[idx++], p);
			};
		}
	};

	$.extend({
		sprintf: function(format) {
			var argv = Array.apply(null, arguments).slice(1);
			return format.replace(re, dispatch(argv));
		},
		vsprintf: function(format, data) {
			return format.replace(re, dispatch(data));
		}
	});
})(jQuery);



/**
 * @author trixta
 */
(function($){
	$.bind = function(object, method){
		var args = Array.prototype.slice.call(arguments, 2);
		return function() {
			var args2 = args.concat($.makeArray( arguments ));
			return method.apply(object, args2);
		};
	};

})(jQuery);


/**
 * jquery.dump.js
 * @author Torkild Dyvik Olsen
 * @version 1.0
 * 
 * A simple debug function to gather information about an object.
 * Returns a nested tree with information.
 * 
 */
(function($) {

	$.fn.dump = function() {
	   return $.dump(this);
	}

    $.dump = function(object) {
       var recursion = function(obj, level) {
          if(!level) level = 0;
          var dump = '', p = '';
          for(i = 0; i < level; i++) p += "\t";
          
          t = type(obj);
          switch(t) {
             case "string":
                return '"' + obj + '"';
                break;
             case "number":
                return obj.toString();
                break;
             case "boolean":
                return obj ? 'true' : 'false';
             case "date":
                return "Date: " + obj.toLocaleString();
             case "array":
                dump += 'Array ( \n';
                $.each(obj, function(k,v) {
                   dump += p +'\t' + k + ' => ' + recursion(v, level + 1) + '\n';
                });
                dump += p + ')';
                break;
             case "object":
                dump += 'Object { \n';
                $.each(obj, function(k,v) {
                   dump += p + '\t' + k + ': ' + recursion(v, level + 1) + '\n';
                });
                dump += p + '}';
                break;
             case "jquery":
                dump += 'jQuery Object { \n';
                $.each(obj, function(k,v) {
                   dump += p + '\t' + k + ' = ' + recursion(v, level + 1) + '\n';
                });
                dump += p + '}';
                break;
             case "regexp":
                return "RegExp: " + obj.toString();
             case "error":
                return obj.toString();
             case "document":
             case "domelement":
                dump += 'DOMElement [ \n'
                      + p + '\tnodeName: ' + obj.nodeName + '\n'
                      + p + '\tnodeValue: ' + obj.nodeValue + '\n'
                      + p + '\tinnerHTML: [ \n';
                $.each(obj.childNodes, function(k,v) {
                   if(k < 1) var r = 0;
                   if(type(v) == "string") {
                      if(v.textContent.match(/[^\s]/)) {
                         dump += p + '\t\t' + (k - (r||0)) + ' = String: ' + $.trim(v.textContent) + '\n';
                      } else {
                         r--;
                      }
                   } else {
                      dump += p + '\t\t' + (k - (r||0)) + ' = ' + recursion(v, level + 2) + '\n';
                   }
                });
                dump += p + '\t]\n'
                      + p + ']';
                break;
             case "function":
                var match = obj.toString().match(/^(.*)\(([^\)]*)\)/im);
                match[1] = $.trim(match[1].replace(new RegExp("[\\s]+", "g"), " "));
                match[2] = $.trim(match[2].replace(new RegExp("[\\s]+", "g"), " "));
                return match[1] + "(" + match[2] + ")";
             case "window":
             default:
                dump += 'N/A: ' + t;
                break;
          }
          
          return dump;
       }
       
       var type = function(obj) {
          var type = typeof(obj);
          
          if(type != "object") {
             return type;
          }
          
          switch(obj) {
             case null:
                return 'null';
             case window:
                return 'window';
             case document:
                return 'document';
             case window.event:
                return 'event';
             default:
                break;
          }
          
          if(obj.jquery) {
             return 'jquery';
          }
          
          switch(obj.constructor) {
             case Array:
                return 'array';
             case Boolean:
                return 'boolean';
             case Date:
                return 'date';
             case Object:
                return 'object';
             case RegExp:
                return 'regexp';
             case ReferenceError:
             case Error:
                return 'error';
             case null:
             default:
                break;
          }
          
          switch(obj.nodeType) {
             case 1:
                return 'domelement';
             case 3:
                return 'string';
             case null:
             default:
                break;
          }
          
          return 'Unknown';
       }
       
       return recursion(object);
    }

})(jQuery);



(function($){
    $.fn.hoverToggleClass = function( className ) {
        this.hover(
            function() { $(this).addClass(className); },
            function() { $(this).removeClass(className); }
        );
    }
} )(jQuery);
