if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}

var sbHeaders = {
	"mathSymbols"	   : "<?php __('Mathematical symbols'); ?>",
	"mathSubscripts"   : "<?php __('Subscripts'); ?>",    
	"mathSuperscripts" : "<?php __('Superscripts'); ?>",      
	"mathFractions"    : "<?php __('Common fractions'); ?>",       
	"cyryllicCapital"  : "<?php __('Cyrillic - capital letter'); ?>",      
	"cyryllicSmall"    : "<?php __('Cyrillic - small letter'); ?>",         
	"greekCapital"     : "<?php __('Greek - capital letter'); ?>",   
	"greekSmall"       : "<?php __('Greek - small letter'); ?>",
	"frenchSmall"      : "<?php __('French - small letter'); ?>",
	"frenchCapital"    : "<?php __('French - capital letter'); ?>",
	"deutschSmall"     : "<?php __('German - small letter'); ?>",
	"deutschCapital"   : "<?php __('German - capital letter'); ?>",
	"spainSmall"       : "<?php __('Spanish - small letter'); ?>",
	"spainCapital"     : "<?php __('Spanish - capital letter'); ?>",
	"italySmall"       : "<?php __('Italian - small letter'); ?>",
	"italyCapital"     : "<?php __('Italian - capital letter'); ?>",       
	"other"            : "<?php __('other_different'); ?>",      
	"frac"			   : "<?php __('indexes and fractions'); ?>"
}

var trans_old = {
	"pl" : {
		"attachmentDeletion": "Na pewno chcesz usunąć załącznik?"
	},
	"en" : {
		"attachmentDeletion": "Are you sure you want to delete that attachment?"
	},
	"ru" : {
		"attachmentDeletion": "Вы уверены, что хотите удалить это приложение?"
	}
};

var trans = {
	"attachmentDeletion": "<?php __('Are you sure you want to delete attachment?'); ?>"
}

var symbolBars = new Array(
   new Array( "mathSymbols"      , "<=>≤≥≈≠≡√∛²³±÷×·∞αβγδµπωΔчФφ∀∃∈∉∋∌∢∧∨⇒⇐⇔∫∑"), //0
   new Array( "mathSubscripts"   , "₁₂₃₄₅₆₇₈₉₀₊₋"), //1
   new Array( "mathSuperscripts" , "¹²³⁴⁵⁶⁷⁸⁹⁰⁺⁻°"), //2
   new Array( "mathFractions"    , "¼½¾⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞"), //3
   new Array( "cyryllicCapital"  , "АБВГДЕЖЗЁИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"), //4
   new Array( "cyryllicSmall"    , "абвгдежзёийклмнопрстуфхцчшщъыьэюя"), //5
   new Array( "greekCapital"     , "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ"), //6
   new Array( "greekSmall"       , "αβγδεζηθικλμνξοπρςστυφχψω"), //7
   new Array( "frenchSmall"		 , "àâçéèêëîïôŕûùüÿœæ"), //8
   new Array( "frenchCapital"	 , "ÉČÁŔÂÎÔŰÇ"), //9
   new Array( "spainSmall"		 , "áéíúñü¿¡"), //10
   new Array( "italySmall"       , "éèàìíîòùú"), //11
   new Array( "deutschSmall"     , "äöüß"), //12
   new Array( "deutschCapital"   , "ÄÖÜ€"), //13
   new Array( "other"            , "ÄÖÜßäöü€£¥¢ƒ®•™") //14
);

var activeStar = '/img/star-active.gif';
var inActiveStar = '/img/star-inactive.gif';
var halfStar = '/img/star-inactive.gif';
function insertChar(chr, area) {
	var tarea = null;
	if (area == 'null'){
		tarea = $('textarea.insertable:first');
	} else {
		tarea = $('#'+area);
	}
	
	if (typeof tarea.tinymce == 'function' && tarea.tinymce() != undefined) { // Edytor to instancja tinymce
		tarea.tinymce().execCommand('mceInsertContent', false, chr);
	} else { // Edytor to zwyczajny textarea
		tarea = tarea.get(0);
		insertAtCursor(tarea, chr);
	}
	return false;
}

function disableSelection(target){
    if (typeof target.onselectstart!="undefined") //IE route
        target.onselectstart=function(){return false}
    else if (typeof target.style.MozUserSelect!="undefined") //Firefox route
        target.style.MozUserSelect="none"
    else //All other route (ie: Opera)
        target.onmousedown=function(){return false}
    target.style.cursor = "default"
}

function strip_tags(input, allowed) {
    allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
    var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
    return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
        return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
    });
}

function sanitizeObject(obj, allowedTags) {
	for (param in obj) {
		if (typeof obj[param] === 'string') {
			obj[param] = strip_tags(obj[param], allowedTags)
		} else if (typeof obj[param] === 'object') {
			sanitizeObject(obj[param], allowedTags)
		}
	}
	return obj;
}

//Nowa funkcjonalność do jQuery
(function($) {
	//Wybiera z elementu "wartości tekstowe" pozostawiając całą resztę na swoim miejscu
	$.fn.textNodes = function() {
	    var ret = [];
	    (function(el){
	        if (!el) return;
	        if ((el.nodeType == 3)||(el.nodeName =="BR"))
	            ret.push(el);
	        else
	            for (var i=0; i < el.childNodes.length; ++i)
	                arguments.callee(el.childNodes[i]);
	    })(this[0]);
	    return $(ret);
	};
	//Zmienia wartość tekstu w elemencie
	$.fn.setFirstRealTextNode= function(txt){
		return this.each(function(){
			var $=jQuery,c=$(this).contents().filter(function(){
				return this.nodeType==3 && $.trim(this.nodeValue).length>0;
				})[0];
		if(c) c.nodeValue=txt;
		})
	};
	//poprawa błędu IE z trimowaniem
	if(!String.prototype.trim) {
		String.prototype.trim = function() {
			return this.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
		}
	}
})(jQuery);

$.extend({URLEncode:function(c){var o='';var x=0;c=c.toString();var r=/(^[a-zA-Z0-9_.]*)/;
while(x<c.length){var m=r.exec(c.substr(x));
  if(m!=null && m.length>1 && m[1]!=''){o+=m[1];x+=m[1].length;
  }else{if(c[x]==' ')o+='+';else{var d=c.charCodeAt(x);var h=d.toString(16);
  o+='%'+(h.length<2?'0':'')+h.toUpperCase();}x++;}}return o;},
URLDecode:function(s){var o=s;var binVal,t;var r=/(%[^%]{2})/;
while((m=r.exec(o))!=null && m.length>1 && m[1]!=''){b=parseInt(m[1].substr(1),16);
t=String.fromCharCode(b);o=o.replace(m[1],t);}return o;}
});
/**
 * 
 * @param bars
 * @param area id obaszaru w ktorym zaczac szukać pola textarea jesli nie ustawione to szuka globalnie
 * @return
 */
function linkAttDels(url) {
	if(url == undefined){
    	url = "/attachments/delete/";
    }
	$("div.thumbnail").each(function(index) {
        var thumb = this;
		
		//var elem_id = $(this).attr('model-id').split(".");
		var elem_attr = $(this).attr('model-id');
		if(elem_attr == undefined){ 
        	var elem_attr = $(this).attr('id');
		}
		var elem_id = elem_attr.split(".");

        
        var att_id = elem_id[1];
			$(thumb).find("div.delLink a").click(function(e) {
	                $("div.thumbnail div.delLink a").fadeOut("slow");
	                $.getJSON(url + att_id, undefined, function(deleted) {
	                    if (deleted) {  
	                        $(thumb).slideUp("slow");
	                        $("div.thumbnail div.delLink a").fadeIn("slow");
	                    }
                	});
            	}).confirm({
		                'msg': '<?php __("Are you sure you want to delete?"); ?>',
		                timeout : 5000,
  						dialogShow : 'fadeIn',
  						dialogSpeed : 'slow',
		                'buttons': {
		                    'ok': '<?php __("yes"); ?>',
		                    'cancel': '<?php __("no"); ?>'
		             }
		        });
	});
};

function uploadifyCompleted(event, queueID, fileObj, response, data) {
    alert(response);
}

/**
* Function : dump()
* Arguments: The data - array,hash(associative array),object
*    The level - OPTIONAL
* Returns  : The textual representation of the array.
* This function was inspired by the print_r function of PHP.
* This will accept some data as the argument and return a
* text that will be a more readable version of the
* array/hash/object that is given.
*/
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;

//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += "    ";

if(typeof(arr) == 'object') { //Array/Hashes/Objects
 for(var item in arr) {
  var value = arr[item];
 
  if(typeof(value) == 'object') { //If it is an array,
   dumped_text += level_padding + "'" + item + "' ...\n";
   dumped_text += dump(value,level+1);
  } else {
   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  }
 }
} else { //Stings/Chars/Numbers etc.
 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
} 

/* loader ajaxa */
function ajaxInject(domId, url) {
    $("#" + domId + " div.loader").html('<div style="width:100%;text-align:center;"><img src="/img/loadingAnimation.gif" /></div>');
    $("#" + domId + " div.loader, " + "#" + domId).slideDown(500);
    $.get(url, null, function (data, textStatus) {
        $("#" + domId + " div.trueContent").html(data);
        $("#" + domId + " div.loader").slideUp(500);
        $("#" + domId + " div.trueContent").slideDown(500);
    });
    
}
function ajaxRawInject(domId, url) { // without loaders
    $.get(url, null, function (data, textStatus) {
        $("#" + domId).html(data);
    });
}
function ajaxLoader(domId) {    
    $("#" + domId + " div.loader").html('<div style="width:100%;text-align:center;"><img src="/img/loadingAnimation.gif" /></div>');
    //$("#" + domId + " div.loader, " + "#" + domId).slideDown(500);
    $("#" + domId + " div.loader, " + "#" + domId).show();
    $("#" + domId + " div.trueContent").slideUp(500);
}
function ajaxContent(domId) { 
    $("#" + domId + " div.loader").html('<div style="width:100%;text-align:center;"><img src="/img/loadingAnimation.gif" /></div>');
    $("#" + domId + " div.loader").slideUp(500);
    $("#" + domId + " div.trueContent").slideDown(500);
}
function ajaxCleanup(domId) {
    $("#" + domId).fadeOut(500);
    $("#" + domId + " div.trueContent").fadeOut(500);
    $("#" + domId + " div.loader, " + "#" + domId).slideUp(500);
    setTimeout('$("#' + domId + ' div.trueContent").empty();', 500);
}
// brzydki hax dla liczników moderacji
var minLeft;
var secLeft;

/**
	cytowanie wypowiedzi innych ludzi
	@param sourceID object - id elementu który jest źródłem tekstu do skopiowania
	@param authorNick string - nick autora tekstu
	@param destID object - id obiektu textarea do ktorego wstawić tekst (tinyMCE)
 */
function quoteSmb(sourceID, authorNick, destID){
	source = $("#"+sourceID);
	content = source.find(".content div").html();
	old = $("#"+destID).tinymce().getBody().innerHTML;
	$("#"+destID).tinymce().execCommand("mceSetContent", false, old+"<blockquote><strong>"+authorNick+"</strong><br/>"+content+"</blockquote><br/><p>&nbsp;</p>");
}
/**
 * dodanie youtube embed linku do tinyMCE na forum
 * @param destID - id obiektu textarea do ktorego wstawic tekst (tinyMCE)
 * @param sourceID - id obiektu textarea do ktorego wstawic tekst (tinyMCE)
 */
function addYouTubeVideo(sourceID, destID) {
	url = $("#"+sourceID).val();
	regex = /http\:\/\/www\.youtube\.com\/watch\?v=([\w-]*)&?.*/;	
	id = url.match(regex);
	if(id == null) {
		alert('<?php __("Incorrect link"); ?>');
		return false;
	}
	id = id[1];
	result = '<iframe src="http://www.youtube.com/embed/'+id+'?wmode=transparent" width="320" height="265" frameborder="0"></iframe>';
	old = $("#"+destID).tinymce().getBody().innerHTML;
	$("#"+destID).tinymce().getBody().innerHTML = old + '<br/>' + result;
	$("#"+sourceID).val('');
	alert('<?php __("Adding film was successful. You\'ll see it after sending a post."); ?>');
	return false;	 
}
/**
 * obsluga dynamicznego edytowania postów
 * @param string editID - id komórki tabeli, zawierajacej teresc postu i ukryty formularz
 */
function editPost(editID, url, userNick){
	body = "";
	id="";
	source = $("#"+editID);
	hiddenElem = source.find("div.editHidden");
	source.find("textarea").each(function(i) {
		tinyMCE.triggerSave();
		body=$(this).tinymce().getContent();		
	});
	source.find(":input[type=hidden]").each(function(i){
		if($(this).attr("name")!="_method")
			id=$(this).val();
	});
	
	params = [];
	params.push({name:'data[Post][content]', value:body});
	params.push({name:'data[Post][id]', value:id});
	$.post(url, params, function(data){
		if(data.success){
			//modyfikacja treści postu
			source.find(".content div").each(function(i){
				$(this).text('');
				$(this).append(data.body);
			});			
			updated = false
			source.find("span.editor span").each(function(i){
				$(this).text("<?php __('by you 1 second ago'); ?>");
				updated = true
			});
			if(!updated){//nie było wcześniej informacji o edycji
				source.find("span.editor").append("<?php __('Recently changed by: <span> you 1 second ago</span>'); ?>");
			}
			source.find("div.textarea").removeClass("error");
			source.find("div.error-message").remove();
			hiddenElem.hide(500);
		}
		else if(data.modelError){
			//hiddenElem.show(300);
			source.find("div.textarea").each(function(i){
				//alert(this);
				$(this).addClass("error");
				$(this).append("<div class='error-message'>"+data.msg+"</div>");
			});
		}
		else{
			alert(data.msg);
		}
		
	}, "json"
		
	);
}

function showEditBox(editBoxID){
	editBox = $("#"+editBoxID);
	title = $("span.threadTitle:first").text();	 
	editBox.find("input[type=text]").val(title);		
	editBox.show(500);
}
function editTitle(editBoxID, url, threadID){	
	title = "";
	editBox = $("#"+editBoxID); 
	title = editBox.find("input[type=text]").val();			
	params = [];
	params.push({name:'data[Thread][subject]', value:title});
	params.push({name:'data[Thread][id]', value:threadID});
	editBox.find("input[type=text]").attr("disabled", "disabled");
	$.post(url, params, function(data){
		editBox.find("input[type=text]").removeAttr("disabled");
		if(data.success){
			$("body	").find('span.threadTitle').text(title);			
			editBox.find("div.text").removeClass("error");
			editBox.find("div.error-message").remove();
			editBox.hide(500);
		}
		else if(data.modelError){
			editBox.find("div.text").each(function(i){				
				$(this).addClass("error");
				$(this).append("<div class='error-message'>"+data.msg+"</div>");
			});
		}
	}, "json");
}

function deleteComment(id, url){
	params = [];
	params.push({name:'data[ProfileComment][id]', value:id});
	$.post(url, params, function(data){
		$('#flashMessage').remove();
		if(data['success']){
			$('#mainRightPanel').prepend('<div id="flashMessage" class="success" style="background-color: #dbed9a">'+data['msg']+'</div>');
			$('#comment'+id).remove();
		}
		else{
			$('#mainRightPanel').prepend('<div id="flashMessage" class="failure" style="background-color: #dbed9a">'+data['msg']+'</div>');
		}
	}, "json");
}
function showStars(divID, fullStars, halfStars, emptyStars){
	$('#'+divID).find("img").each(function(i){
		if(i<fullStars)
			$(this).attr('src', activeStar);
		else if(i<fullStars+halfStars)
			$(this).attr('src', halfStar);
		else
			$(this).attr('src', inActiveStar);
	});
}
function turnOnStars(divID, starNr){
	//alert(divID);
	$('#'+divID).find("img").each(function(i){
		if(i<=starNr)
			$(this).attr('src', activeStar);
		else
			$(this).attr('src', inActiveStar);
	});
}
function vote(resp_id, vote, url){
	params = [];
	params.push({name:'data[Vote][response_id]', value:resp_id});
	params.push({name:'data[Vote][vote]', value:(vote+1)});
	$.post(url, params, function(data){
		
		voteID = '#vote'+resp_id;
		if(data.success){
			$(voteID).find("img").remove();
			$(voteID).prepend("<?php __('Thank you_we'); ?>");
			mark = ''+data.mark;
			markN = data.mark;
			if(mark.length>4)
				markN = Math.round(markN*100)/100;
			$(voteID).find("div span").text(markN);
		}
		else{
			wrrID = "worn"+resp_id;
			$('#'+wrrID).remove();
			$(voteID).prepend("<div id="+wrrID+">"+data.msg+"</div>");
			//alert(data.msg);
		}
	}, "json");
}

$(document).ready(function(){
	/* 
	obluga fancybox
	*/
	fancy_init();
});

function fancy_init(){
	$('a.thickbox').each(function(index){
		var url = $(this).attr('href');
		var paramsStart = url.indexOf('?');
		var params = [];
		var fancyParams = {};
		var i = 0;
		
		if (paramsStart > -1){ 
			params = url.substring(paramsStart+1).split('&');
		}
		
		for (i;  i < params.length; i++) {
			var param = params[i];
			var pos = param.indexOf("fn_");
			
			parts = param.split("=");
			
			if (pos != -1){
				parts[0] = parts[0].substring(pos+3);
			}
			fancy = pos != -1 || parts[0] == "width" || parts[0] == "height";
			if (fancy){
				fancyParams[parts[0]] = getFancyValue(parts[1]);
			}
		}
		if (fancyParams.width != undefined && fancyParams.autoDimensions == undefined){
			fancyParams.autoDimensions = false;
		}
		$(this).fancybox(fancyParams);	
	});
}

function getFancyValue(val){
	var y = parseInt(val);
	if (isNaN(y)){
	 if (window[val]!= undefined) return window[val];
	 return val;
	} 
	return y;
	}

function showStarsInForm(divID, fullStars, halfStars, emptyStars){
	$('#'+divID).find("input[type=image]").each(function(i){
		if(i<fullStars)
		  $(this).attr('src', activeStar);
		else if(i<fullStars+halfStars)
		  $(this).attr('src', halfStar);
		else
		  $(this).attr('src', inActiveStar);
	});
}
function turnOnStarsInForm(divID, starNr){
	//alert(divID);
	$('#'+divID).find("input[type=image]").each(function(i){
		if(i<=starNr)
		  $(this).attr('src', activeStar);
		else
		  $(this).attr('src', inActiveStar);
	});
}

function toggleResonSwitchButton(id, showTxt, hideTxt){
	switchId = '#taskResonSwitchButton'+id;
	text = $(switchId).text();
	if (text == "<?php __('View reasons'); ?>") {
		$(switchId).text(showTxt);
	} else {
		$(switchId).text(hideTxt);
	}
}

function useReason(id, delId, textArea){
	tarea = $('#'+textArea);
	tarea = tarea.get(0);
	console.log($(tarea).val(""));
	insertAtCursor(tarea, $('#'+id).text());
	
}
function toggleWhole(all, shortx, id){
	text = $('#reasonSwitcher'+id).text();
	if (text == '<?php __("View all_show_whole"); ?>'){
		$('#reasonSwitcher'+id).text('<?php __("Hide all"); ?>');
		$('#reasonSwitcher'+id).addClass('red');
		$('#reasonSwitcher'+id).parent().parent().css('background', '#ffffcc');
	} else {
		$('#reasonSwitcher'+id).text('<?php __("View all_show_whole"); ?>');
		$('#reasonSwitcher'+id).removeClass('red');
		$('#reasonSwitcher'+id).parent().parent().css('background', 'none');
	}
	$('#'+shortx).toggle();
	$('#'+all).toggle();
}
function nl2br (str, is_xhtml) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Philip Peterson
    // +   improved by: Onno Marsman
    // +   improved by: Atli Þór
    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Maximusya
    // *     example 1: nl2br('Kevin\nvan\nZonneveld');
    // *     returns 1: 'Kevin<br />\nvan<br />\nZonneveld'
    // *     example 2: nl2br("\nOne\nTwo\n\nThree\n", false);
    // *     returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
    // *     example 3: nl2br("\nOne\nTwo\n\nThree\n", true);
    // *     returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'

    var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';

    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}
/*
 * 
 * Funkcje odpowiadające za symbole
 * 
 */
function showLangs(event, element) {
	event.preventDefault();
	$(element).parent().parent().next().toggle();
}
function showBar(bars, area, symbolBarId) {
    var i;
    for (i = 0; i < bars.length; i++) {
        var barIndex = bars[i];
	    var barId = symbolBars[barIndex][0];
	    var barName = sbHeaders[barId];
	    var chars = symbolBars[barIndex][1];
	    var domId = "symbols-" + barId;
	    if (area != undefined && area != null){
	    	domId += area;
	    }
	    if (document.getElementById(domId) == null) {
	        var barDiv = $("#"+symbolBarId);
	        barDiv.show();
	        var appender = "<div id='" + domId + "' style='display:none;' class='symbolBar'><div class='name text'>" + barName + ":</div><div class='chars text'>";
	        var j;
	        for (j = 0; j < chars.length; j++) {
	            var chr = chars.charAt(j);
	            var clearer = '';
	            if (chr == 'Δ' && barIndex == 0) { // opera fix
	            	clearer = 'clear:left;'
	            }
	            appender += "<a href='#' style='float:left;" + clearer + "' onclick=\"return insertChar('" + chr + "', '"+area+"');\">" + chr + "</a>";
	            //alert(chars.charAt(j));
	        }
	        if (barIndex == 0) {
	        	areaText = 'null';
	        	if(alert != null){
	        		areaText = '\''+area+'\'';
	        	}
               appender += "<a href='#' style='width:auto;font-size:12px;padding:0 5px 0 5px;' onclick=\"return showBar(new Array(1, 2, 3),"+areaText+",'"+symbolBarId+"');\">" +  sbHeaders['frac'] + "</a>";
            }
	        appender += "<div class='cleaner'></div></div></div>";
	        barDiv.append(appender);
	    }
	    $("#" + domId).slideToggle();
    }
    return false;
}
/**
 * Dopisanie metody bind :)
 * Nie ruszac, cale taggify jest na tym oparte i przyszle planowane zadanium ;p
 */
Function.prototype.bind || (Function.prototype.bind = function(ctx){
	var fn = this, 
		args = Array.prototype.slice.call(arguments,1);
		
	return function() {
		return fn.apply( ctx, args.concat(Array.prototype.slice.call(arguments)) );
	};
});
/**
 * Dopisanie metody clone
 */
Function.prototype.clone || (Function.prototype.clone = function() {
    var fct = this;
    var clone = function() {
        return fct.apply(this, arguments);
    };
    clone.prototype = fct.prototype;
    for (property in fct) {
        if (fct.hasOwnProperty(property) && property !== 'prototype') {
            clone[property] = fct[property];
        }
    }
    return clone;
});

if(false && typeof $.fn.placeholder === 'function') {
	$(document).ready(function() {
		$('input[placeholder], textarea[placeholder]').placeholder();
	});
}

/**
 * Sprintf
 */


sprintfWrapper = {
	init : function () {
 
		if (typeof arguments == "undefined") { return null; }
		if (arguments.length < 1) { return null; }
		if (typeof arguments[0] != "string") { return null; }
		if (typeof RegExp == "undefined") { return null; }
 
		var string = arguments[0];
		var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
		var matches = new Array();
		var strings = new Array();
		var convCount = 0;
		var stringPosStart = 0;
		var stringPosEnd = 0;
		var matchPosEnd = 0;
		var newString = '';
		var match = null;
 
		while (match = exp.exec(string)) {
			if (match[9]) { convCount += 1; }
 
			stringPosStart = matchPosEnd;
			stringPosEnd = exp.lastIndex - match[0].length;
			strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
 
			matchPosEnd = exp.lastIndex;
			matches[matches.length] = {
				match: match[0],
				left: match[3] ? true : false,
				sign: match[4] || '',
				pad: match[5] || ' ',
				min: match[6] || 0,
				precision: match[8],
				code: match[9] || '%',
				negative: parseInt(arguments[convCount]) < 0 ? true : false,
				argument: String(arguments[convCount])
			};
		}
		strings[strings.length] = string.substring(matchPosEnd);
 
		if (matches.length == 0) { return string; }
		if ((arguments.length - 1) < convCount) { return null; }
 
		var code = null;
		var match = null;
		var i = null;
 
		for (i=0; i<matches.length; i++) {
 
			if (matches[i].code == '%') { substitution = '%' }
			else if (matches[i].code == 'b') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'c') {
				matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'd') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'f') {
				matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'o') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 's') {
				matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'x') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'X') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
			}
			else {
				substitution = matches[i].match;
			}
 
			newString += strings[i];
			newString += substitution;
 
		}
		newString += strings[i];
 
		return newString;
 
	},
 
	convert : function(match, nosign){
		if (nosign) {
			match.sign = '';
		} else {
			match.sign = match.negative ? '-' : match.sign;
		}
		var l = match.min - match.argument.length + 1 - match.sign.length;
		var pad = new Array(l < 0 ? 0 : l).join(match.pad);
		if (!match.left) {
			if (match.pad == "0" || nosign) {
				return match.sign + pad + match.argument;
			} else {
				return pad + match.sign + match.argument;
			}
		} else {
			if (match.pad == "0" || nosign) {
				return match.sign + match.argument + pad.replace(/0/g, ' ');
			} else {
				return match.sign + match.argument + pad;
			}
		}
	}
}
 
sprintf = sprintfWrapper.init;

in_array = function(p_val,arrayObject) {
	for(var i = 0, l = arrayObject.length; i < l; i++) {
		if(arrayObject[i] == p_val) {
			return true;
		}
	}
	return false;
}

function strpos (haystack, needle, offset) {
    var i = (haystack + '').indexOf(needle, (offset || 0));
    return i === -1 ? false : i;
}

/**
 * Object sorting method
 * @param givenObject
 * @returns
 */

function sortObject(givenObject,reverse) {
	var nameArray = [],
		newObject = {};
	
	for(name in givenObject) {
		nameArray.push(name);
	}
	nameArray.sort();
	if(reverse) {
		nameArray.reverse();
	}
	for(nameA in nameArray) {
		nameA = nameArray[nameA];
		if(typeof givenObject[nameA] === 'function') {
			continue;
		}
		newObject[nameA] = givenObject[nameA];
	}
	givenObject = newObject;
	return givenObject;
}
