if (!console) {
    var console = {
        log: function(){},
        debug: function(){},
        dir: function(){},
        firebug: null
    }
}

(function($) {

jQuery.extend({
    
    jsHttpRequest: function(options)
    {
        var options = jQuery.extend({
            url:     '/',
            data:    {},
            onReady: function(){},
            cache:   false
        }, options);
                
        JsHttpRequest.query(
            options.url,
            options.data,
            function(result, text) {

				if(result) {
	                if (typeof(result._debug) != 'undefined') {
	                    console.log(result._debug);
	                }
	                
	                if (typeof(result._trace) != 'undefined') {
	                    $.each(result._trace, function(i, message) {
	                        console.log(message);   
	                    });
	                }
                }
                
                if (typeof(options.onReady) == 'function') {
                    options.onReady(result, text);
                }
                
            },
            !options.cache
        );
    }
});

jQuery.fn.extend({
    
    serializeHash: function()
    {
        var hash = {};
        $.each(this.serializeArray(), function(i, el) {
            el.name = el.name.replace(/\[\]$/, '');
            
            if (typeof(hash[el.name]) == 'undefined')
                return hash[el.name] = el.value; 
            
            if (!hash[el.name].push)
                hash[el.name] = [hash[el.name]];
            
            hash[el.name].push(el.value);
        });
        return hash;
    },
    
    red: function()
    {
        return $(this).css('border', 'red 1px solid');
    },
    
    removeSlow: function()
    {
        return $(this).animate({ opacity: 'hide', height: 'hide' }, 'slow', null, function(){ $(this).remove(); });
    }
});

$F = function(elm) {
    return $(elm).val();
}

clone = function(object) {
    return $.extend({}, object);
}

differenceOfDays = function(start, end)
{
    start = start.split('.');
    end   = end.split('.');
    start = new Date(start[2], start[1], start[0]);
    end   = new Date(end[2], end[1], end[0]);
    return Math.ceil((end - start) / (1000 * 86400));
}

Tools = {
		   _baseServiceImagePath: '/public/images/service/',
		   _loaderProgress: 'ajaxloadergrey.gif',
		   
		   setStyle: function(stylename)
		   {
		      Tools._loaderProgress = stylename + '.gif';
		   },
		   
		   replaceLoader: function(elem, text)
		   {
		        text = text?text+"<br />":"";
		        elem.html("<div id='loaderimage'  style='width: 100%; text-align:center; padding-top: 20px; '>"+ text +"<img src='"+ Tools._baseServiceImagePath + Tools._loaderProgress +"'></div>");
		   },
		   
		   addLoaderTop: function(elem, text)
		   {
		        text = text?text+"<br />":"";
		        elem.prepend("<div id='loaderimage' style='width: 100%; text-align:center; padding-top: 20px; '>"+ text +"<img src='"+ Tools._baseServiceImagePath + Tools._loaderProgress +"'></div>");
		      
		   },
		   
		   removeLoader: function()
		   {
		       $('#loaderimage').remove();
		   },
		   
		   addLoaderBottom: function(elem, text)
		   {
		        text = text?text+"<br />":"";
		        elem.append("<div id='loaderimage' style='width: 100%; text-align:center; padding-top: 20px; '>"+ text +"<img src='"+ Tools._baseServiceImagePath + Tools._loaderProgress +"'></div>");
		   },
		   
		   enableMainLoader: function()
		   {
		       $('#mainloader').html("<div style='width: 100%; text-align: center; margin: 20px;'><img src='/public/images/service/ajaxloaderwhite.gif'><br />идет загрузка...</div>");
		   },
		   
		   disableMainLoader: function()
		   {
		       $('#mainloader').text('');
		   },
		   
		   enableTinyMCE: function()
		   {
		        $('textarea:tinymce').each(function () { $(this).tinymce().remove(); });
		  		$('textarea').tinymce(
				{
					// Location of TinyMCE script
					script_url : '/public/js/tiny_mce/tiny_mce.js',

					// General options
					theme : "advanced",
					plugins : "safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",

					// Theme options
					theme_advanced_buttons1 : "bold,italic,underline,|,justifyleft,justifycenter,justifyright,|,forecolor,sub,sup,|,bullist,numlist,|,link,unlinkr,image,forecolor,|,fullscreen, preview,code",
					theme_advanced_buttons2 : "",
					theme_advanced_buttons3 : "",
					theme_advanced_toolbar_location : "top",
					theme_advanced_toolbar_align : "left",
					theme_advanced_statusbar_location : "bottom",
					theme_advanced_resizing : true,
					relative_urls : false
				}  
		  		);   
		   },
		   
		   enableDatePicker: function(elem, options)
		   {
		   	   var options = !!options?options:{dateFormat: 'dd.mm.yy'};
		       if(elem){
		          elem.datepicker(options);
		       }else{
		          $(".datepicker").datepicker(options);
		       }
		   }
}


Message = {
	    show: function(message, type)
	    {
	    	$('#top-message').html(message).addClass(type).slideDown('slow');	
	    },
	    
	    error: function(message)
	    {
	        Message.show(message, 'error');
	    },
	    
	    success: function(message)
	    {
	        Message.show(message, 'success');
	    },
	    
	    hide: function()
	    {
	       $('#top-message').slideUp('slow');
	    }
	}

Form = {
		_dialog: null,
		
	    _isFormValid: true,
	    
	    _showAjaxLoader: function(elem)
	    {
	    	$('h1', elem).after('<div class="ajax-load">' + (elem.attr('ajax-loader-message')?elem.attr('ajax-loader-message'):'идет обработка формы') + '...<br /><img src="/public/images/ajax-loader.gif"></div>');
	    },
	    
	    _hideAjaxLoader: function()
	    {
	    	$('div.ajax-load').remove();
	    },

	    _reset: function(elem)
	    {
	       Form._isFormValid = true;
	    
	       $('input', elem).each(
	          function(e){
	             $(this).removeClass('error');
	          }
	       );
	       $('span.error', elem).each(
	          function(e){
	             $(this).remove();
	          }
	       );
	       
	       Message.hide();
	    },
	    
	    message: function(params)
	    {
	    	var containerName = 'modal-message';
			$('#' + containerName).remove();
	        Form._dialog = $('<div class="' + containerName + '">' + params.text + '</div>').dialog({
	            title: params.header,
	            height: params.height,
	            width: params.width,
	            modal: params.isModal,
	            buttons: { 
	                'Закрыть': function() { Form._dialog.dialog('destroy'); $('#' + containerName).remove(); }
	            } 
	        });	    	
	    },
	    
	    dialog: function(params)
	    {
	    	var containerName = params.containerName;
	    	var header = params.header;
			$('#' + containerName).remove();
	        Form._dialog = $('<div class="' + containerName + '" style="background: url(/public/projectz/images/ajax-loader.gif) no-repeat 48% 40%;">&nbsp;</div>').dialog({
	            title: header,
	            height: params.height,
	            width: params.width,
	            modal: params.isModal,
	            buttons: { 
	                'Отправить': function() { 
	                	 Form.save( $('#' + containerName), function(){
				             Form._dialog.dialog('destroy'); 
				             $('#' + containerName).remove();
				             Form.message({
				            	header 		  : params.successHeader,
					    		height        : 220,
					    		width         : 350,
					    		isModal		  : true,
					    		text		  : params.successText
				             });
	                	 });
	                 },
	                'Закрыть': function() { Form._dialog.dialog('destroy'); $('#' + containerName).remove(); }
	            } 
	        });
	        
	        $.jsHttpRequest({
	            url: params.formUrl,
	            data: params.params,
	            onReady: function(result, text) {
	                $(Form._dialog).html(text).css('background', '');
	                Tools.enableDatePicker();
	            },
	            cache: false,
	            target: Form._dialog
	         });      	
	    },	    
	    
	    save: function(formElement, callback)
	    {
	    	var form = !!formElement ? formElement : Form._getCurrentForm();
	    	Form._showAjaxLoader(form);
	    	if(!Form.check()) return;
	    	if(form.attr('method') !== 'ajax'){ 
	    	   form.submit();
	    	   return;
	    	}else{
		        $.jsHttpRequest({
		             url: form.attr('action') + 'save/',
		             data: {'q' : form.get(0)},
		             onReady: function(result, text) {
		                 if(text) console.log(text);
		                 if(result && result.error){
							$.each(result, function(index, value) { 
							   Form._processField( $('[name=' + index + ']:first', form), value ); 
							});
		                 }else{
		                	 
		                	 if (typeof(callback) == 'function') {
		                         callback();
		                     }else{
				                 if($('input[name=id]', form).val()){
					                 	$('div.object'+$('input[name=id]').val()).replaceWith(text);
					             }else{
					                 	$('div.edit-block').prepend(text);
					             }
				                 Message.success('Ваши данные успешно сохранены');
				                 form.slideUp('slow');
		                     }
		                 }
		             }
		         });     	   
	    	}   
	    },

	    check: function(elem)
	    {
	        Form._reset(elem);
	    	$('input', elem).each(
	    	   function(e){
	    		   Form._isRequire($(this));
	    		   Form._isDigital($(this));
	    		   Form._isEmail($(this));
	    		   Form._isWww($(this));
	    		   Form._checkMaxLen($(this));
	    	   }
	    	);
	    	if(!Form._isFormValid) Message.error('При обработки формы произошли ошибки.');
	    	Form._hideAjaxLoader();
	    	return Form._isFormValid;
	    	
	    },
	    
	    _isRequire: function(elem)
	    {
	       if(elem.hasClass('require') && !elem.val()){
	          Form._processField(elem, 'Вы не заполнили обязательное поле');
	          Form._isFormValid = false;
	          return true;
	       }
	       return false;
	    },
	    
	    _isDigital: function(elem)
	    {
	 	   var re = /^\d+$/i; 
	 	   return Form._testRegexp('digital', elem, re, 'Неверно заполнено числовое поле'); 
	    },
	    
	    _isEmail: function(elem)
	    {
	       var re = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i;
	 	   return Form._testRegexp('email', elem, re, 'Значение не верно. Введите e-mail в это поле'); 
	    },
	    
	    _isWww: function(elem)
	    {
	       var re = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i;
	 	   return Form._testRegexp('www', elem, re, 'Значение не верно. Введите адрес сайта в это поле'); 
	    },
	    
	    _checkMaxLen: function(elem)
	    {
	        if(elem.attr('maxlen') && elem.val().length > elem.attr('maxlen')){
	          Form._processField(elem, 'Количество символов в данном поле больше допустимого на ' + ( elem.val().length - elem.attr('maxlen') ) + ' символов' );
	          Form._isFormValid = false;
			  return true;        
	        }else{
	          return false;
	        }
	    },
	    
	    _processField: function(elem, message)
	    {
	          elem.addClass('error');
	          elem.after('<span class="error">' + (elem.attr('message')?elem.attr('message'):message) + '</span>');
	    },
	    
	    _testRegexp: function(className, elem, re, message)
	    {
	       if(elem.hasClass(className) && elem.val() && !re.test(elem.val())){
	          Form._processField(elem, message);
	          Form._isFormValid = false;
	          return true;
	       }else{
	          return true;
	       }
	    },
	    
	    edit: function(id)
	    {
	        Form._getCurrentForm().slideDown('slow');
	        if(Form._getCurrentForm().attr('callback')){
	            var callback = eval(Form._getCurrentForm().attr('callback'));
	            if (typeof callback == 'function') callback(id);
	        }
	        if(!id){
	        	$(':input', Form._getCurrentForm()).each(
	        	    function(x){
	        	        if($(this).attr('type') !== 'button' && $(this).attr('type') !== 'checkbox' && $(this).attr('type') !== 'radio'){
	        	            $(this).val('');
	        	        }
	        	        if($(this).attr('type') == 'checkbox' || $(this).attr('type') == 'radio'){
	        	        	$(this).prop('checked', false);
	        	        }
	        	    }
	        	);
	        }else{
		        Form._showAjaxLoader(Form._getCurrentForm());
		        $.jsHttpRequest({
		             url: Form._getCurrentForm().attr('action') + 'edit/',
		             data: {'id': id},
		             onReady: function(result, text) {
		            	 $(':input', Form._getCurrentForm()).each(
		                      function(x){
		                          if(typeof(result[$(this).attr('name')]) !== 'undefined'){
		                              if($(this).attr('type') == 'checkbox'){
		                            	  $(this).prop('checked', parseInt(result[$(this).attr('name')]) ? true : false );
		                              }else{
		                            	  $(this).val(result[$(this).attr('name')]?result[$(this).attr('name')]:'');
		                              }
		                          }
		                      }
		                  );
		                  Form._hideAjaxLoader(Form._getCurrentForm());
		             }
		         });  
	         }         
	    },
	    
	    del: function(id)
	    {
	        $.jsHttpRequest({
	             url: Form._getCurrentForm().attr('action') + 'delete/',
	             data: {'id': id},
	             onReady: function(result, text) {
	                if(!text){
	                    $('.object'+id).slideUp('slow');
	                }
	             }
	         });      
	    },
	    
	    deleteXTRImage: function(elem, id)
	    {
	        if(!confirm('Вы действительно хотите удалить картинку?')) return;
	        $.jsHttpRequest({
	             url: Form._getCurrentForm().attr('action') + 'deletextrimg/',
	             data: {'id': id},
	             onReady: function(result, text) {
	                if(!text){
				        $(elem).parent().parent().slideUp('slow');
	                }
	             }
	         });      
	        
	    },
	    
	    changeImageSrcType: function(elem)
	    {
	       $('input[type=text]', $(elem).parent().parent()).toggle();
	       $('input[type=file]', $(elem).parent().parent()).toggle();
	       $(elem).text( $(elem).text() == 'url' ? 'file' : 'url' );
	    },
	    
	    enableTinyMce: function(){
	    	Tools.enableTinyMCE();
	    },
	    
	    _getCurrentForm: function()
	    {
	        return $('form');
	    }
	}

$.extend(String.prototype, {
    
    occupied: function (pattern) {
        var pos = this.indexOf(pattern);
        for (var count = 0; pos != -1; count++)
           pos = this.indexOf(pattern, pos + pattern.length);
        return count;
    },
    
    /**
     * Транслит руских букв в латинские
     * @param string text
     * @return string
     */
    translit: function () {
        var text   = this;
        var ru_str = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя';
        var en_str = [
        'A','B','V','G','D','E','Jo','Zh','Z','I','Y','K','L','M','N','O','P','R','S','T','U','F',
        'Kh','Ts','Ch','Sh','Shch','','Y','','E','Yu','Ya',
        'a','b','v','g','d','e','jo','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f',
        'kh','ts','ch','sh','shch','','y','','e','yu','ya'];

        for(var i = 0, out = [], count = text.length; i < count; i++) {
            var s = text.charAt(i), n = ru_str.indexOf(s);
            out[out.length] = (n >= 0) ? en_str[n] : s;
        }
        return out.join('');
    },
    
    // подсавляет к числу существительное в соответствующей форме. 
    // например: 3.inciting('турист', 'туриста', 'туристов') -> 3 туриста
    inciting: function(form1, form2, form5)
    {
        var num = Math.abs(parseInt(this));
        var n = num % 100, n1 = num % 10;
        form5 = form5 || form2;
        if (n > 10 && n < 20) return this + ' ' + form5;
        if (n1 > 1 && n1 < 5) return this + ' ' + form2;
        if (n1 == 1) return this + ' ' + form1;
        return this + ' ' + form5;
    },
    
    // делает первый символ с большой буквы, остальные с маленькой. иванов -> Иванов
    capitalize: function()
    {
        return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
    },
    
    // заменяет все символы с 160 по 255-й на соответствующий entitles код. например &#231;
    unicodeToEntitles: function()
    {
        for (var i = 0, output = this, cnt = this.length; i < cnt; i++) {
            if (this.charCodeAt(i) < 160 || this.charCodeAt(i) > 255) continue;
            output = output.replace(this[i], '&#' + this.charCodeAt(i) + ';');
        }
        return output + '';
    },
    
    // переопределение escape, т.к. обычная функция вместо русских букв выдает фигню
    escapeCyr: function()
    {
        var trans = [], ret = [];
        for (var i = 0x410; i <= 0x44F; i++)
            trans[i] = i - 0x350; // А-Яа-я
        trans[0x401] = 0xA8;    // Ё
        trans[0x451] = 0xB8;    // ё
        
        // Составляем массив кодов символов, попутно переводим кириллицу
        for (var i = 0, count = this.length; i < count; i++) {
            var n = this.charCodeAt(i);
            if (typeof trans[n] != 'undefined')
                n = trans[n];
            if (n <= 0xFF)
                ret.push(n);
        }
        return escape(String.fromCharCode.apply(null, ret));
    },
    
    // переопределение escape, т.к. обычная функция вместо русских букв выдает фигню
    unescapeCyr: function()
    {
        var trans = [], ret = [];
        for (var i = 0x410; i <= 0x44F; i++)
            trans[i] = i - 0x350; // А-Яа-я
        trans[0x401] = 0xA8;    // Ё
        trans[0x451] = 0xB8;    // ё
        
        // Составляем массив кодов символов, попутно переводим кириллицу
        for (var i = 0, count = this.length; i < count; i++) {
            var n = this.charCodeAt(i);
            if (typeof trans[n] != 'undefined')
                n = trans[n];
            if (n <= 0xFF)
                ret.push(n);
        }
        return escape(String.fromCharCode.apply(null, ret));
    }
});

Number.prototype.inciting = String.prototype.inciting;
window.escapeModify = function(str) { return str.escapeCyr(); }

})(jQuery);


/**
 * Плагин для работы с JSON, содержит 2 функции
 * 
 * string = $.toJSON(value);
 * object = $.parseJSON(string, [safeMode]);
 */
(function($){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},s={'array':function(x){var a=['['],b,f,i,l=x.length,v;for(i=0;i<l;i+=1){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a[a.length]=v;b=true}}}a[a.length]=']';return a.join('')},'boolean':function(x){return String(x)},'null':function(x){return"null"},'number':function(x){return isFinite(x)?String(x):'null'},'object':function(x){if(x){if(x instanceof Array){return s.array(x)}var a=['{'],b,f,i,v;for(i in x){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a.push(s.string(i),':',v);b=true}}}a[a.length]='}';return a.join('')}return'null'},'string':function(x){if(/["\\\x00-\x1f]/.test(x)){x=x.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c}c=b.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16)})}return'"'+x+'"'}};$.toJSON=function(v){var f=isNaN(v)?s[typeof v]:s['number'];if(f)return f(v)};$.parseJSON=function(v,safe){if(safe===undefined)safe=$.parseJSON.safe;if(safe&&!/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))return undefined;return eval('('+v+')')};$.parseJSON.safe=false})(jQuery);

