//if (typeof jQuery != 'function') {
//    alert('Jquery required');
//}

var App = App || {};
App.is_ie  = (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) );
App.is_ie5 = (this.is_ie && /msie 5\.0/i.test(navigator.userAgent));
App.is_opera = /opera/i.test(navigator.userAgent);
App.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

App.i18n = {
    dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
	dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
	monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
	monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};

App.config = {};


App.showError = function(msg) {
    if (App.i18n[msg]) {
        alert(App.i18n[msg]);
    } else {
        alert(msg);
    }
}

App.redirect = function(url) {
    window.location.href = url;
}

/*
App.load = function(src, id) {
    var s  = document.createElement('script');
    s.type = 'text/javascript';
    if (id) s.id   = id;
    s.src  = src;
    document.getElementsByTagName('head')[0].appendChild(s);
}
*/

if (typeof log4javascript != 'undefined') {
    App.logger = log4javascript.getLogger('default');
    var apnd = new log4javascript.AjaxAppender("/js/log4js/log4js.php");
    apnd.setThreshold(log4javascript.Level.ERROR);
    App.logger.addAppender(apnd);

    App.logger.ignore = [];
    App.logger.ignore.push(/Error loading script/i);//???
    App.logger.ignore.push(/GA_google/i);//if client uses ad blocker
    App.logger.ignore.push(/GS_google/i);//if client uses ad blocker

    App.logger.ignored = function(msg) {
        for (var i=0; i<App.logger.ignore.length; i++) {
            if (App.logger.ignore[i].test(msg)) return true;
        }
        return false;
    }
}


App.handleException = function(e) {
    if (typeof App.logger != 'undefined') {
        if (e.message) {
            msg = e.message;
        } else if (e.description){
            msg = e.description;
        } else if (e.toString) {
            msg = e.toString()
        } else {
            msg = e;
        }

        if (App.logger.ignored(msg)) return false;

        if (e.lineNumber) {
            msg += ' [line: ' + e.lineNumber + ']';
        }

        App.logger.error(msg);
        return true;
    }

    return false;
}

App.request = function(params, onSuccess, onError) {
    $j.ajax({
        url     : params.url,
        type    : params.type,
        data    : params.data,
        dataType: 'json',
        success: function(data, state, xhr) {
            onSuccess(data, state);
        },
        error: function(xhr, state){
            onError(state);
        }
    });
}

App.publish = function(topic, args) {
    $j.publish(topic, args);
};

App.subscribe = function(topic, cb) {
    $j.subscribe(topic, cb);
};

App.subscribe('error', function(error){
    App.handleException(error);
});



if (!Function.prototype.bind) {
    Function.prototype.bind = function(oThis) {
        if (typeof this !== 'function') {
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }

        var aArgs = Array.prototype.slice.call(arguments, 1),
            fToBind = this,
            fNOP = function() {},
            fBound = function() {
                return fToBind.apply(
                    (this instanceof fNOP) ? this : oThis || window,
                    aArgs.concat(Array.prototype.slice.call(arguments))
                );
            };

        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();

        return fBound;
    };
}


/*
window.onerror = function(msg, url, line) {

    if (typeof App.logger != 'undefined') {
        if (App.logger.ignored(msg)) return false;

        App.logger.error(msg + ' [line: ' + line + ']');
        return false;
        //return true;
    }

    return false;
}

*/
var x=0;
var browserName = window.navigator.appName;
var browserVersion = window.navigator.appVersion;
var enableEvent = (browserName=='Netscape')?0:((parseInt(browserVersion.substring(0,1))<4)?0:1);

var maxLen = 300;
var oldMessage = ''; 
var InAction = 0;

function textarea_onkeydown(paObject){	
  if(paObject.value.length + InAction < maxLen ){
	oldMessage = paObject.value;
	if(enableEvent==1){
	  InAction = ((window.event.keyCode>15) && (window.event.keyCode<19))?0:1;
	  window.event.cancelBubble = true;
	} 
	else 
	  ++InAction;
  } 
  else{
	if(enableEvent==1){
	  if(window.event.keyCode >=65 ){
		window.event.returnValue = false;
		window.event.cancelBubble = true;
	  }
	} 
	else 
	  return false;
  }
}
		
function textarea_onkeyup(paObject){
  var newMessage = paObject.value;
		  
  if(newMessage.length > maxLen ){
	paObject.value = oldMessage;
	if(enableEvent==1){
	  window.event.returnValue = false;
	  window.event.cancelBubble = true;
	}
  }  
  InAction = 0;
}


function isInteger( val ) {
   if(isNaN(parseInt(val))){
	 return false;
   }	 
   return true;	 
}

function isValidEmail(email){
   return email.match(/^[a-z0-9-_\.+]+\@([a-z0-9-]+\.)+[a-z]{2,6}$/gi);
}	

function isValidPasswd(paPasswd) {
  return new RegExp("^([a-z0-9]{6,})$", "i").test(paPasswd);
}


function isValidLink(paLink){
  return new RegExp("http:|ftp:|news:[a-z0-9.]+", "ig");
}	

function isJpeg(paFileName){

 if(paFileName.substring(paFileName.lastIndexOf(".")+1,paFileName.length).toLowerCase()=="jpg" 
    || paFileName.substring(paFileName.lastIndexOf(".")+1,paFileName.length).toLowerCase()=="jpeg")
   return true;
 else
   return false;
}

function windowOpen(url,name,features,replace){
   var win=window.open(url,name,features,replace);
   win.focus();
}

function URLOpen(url){
  var win=window.open(url);
  win.focus();
}     

function protectEmail(email) {
    var s=new String(email);
    s=s.replace('@','(&#64;)');
    while (s.indexOf('.')!=-1) {
        s=s.replace('.','(&#46;)');
    }    
    return s;
}

function unprotectEmail(email) {
    var s=new String(email);
    s=s.replace('(@)','@');
    while(s.indexOf('(.)') != -1) { 
        s=s.replace('(.)','.');
    }    
    return s;
}

function mailTo(to,subject){
  window.location = "mailto:"+unprotectEmail(to)+'\n?subject='+escape(subject);
}
 
function mailTo2(to,subject,body){
  window.location = "mailto:"+unprotectEmail(to)+'\n?subject='+escape(subject)+'&body='+escape(body);
}

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

function getCookie(n) {
  var s = document.cookie;
  if(!s.length)
    return null;

  var beg = s.indexOf(n+"=");
  if(beg == -1)
    return null;

  beg += n.length + 1;
  var end = s.indexOf(";", beg);
  if(end == -1)
    end = s.length;
  return unescape(s.substring(beg, end));
}

function setCookie(name, value, expires, path, domain, secure) {
  var s = "";
  if(expires) s += "; expires=" + expires;
  if(path   ) s += "; path="    + path;
  if(domain ) s += "; domain="  + domain;
  if(secure ) s += "; secure="  + secure;
  //TODO:EASY: escape() is obsolete, which new version belongs here?
  document.cookie = name + "=" + escape(value) + s;
}

function delCookie(name) {
  setCookie(name, "", -1);
}

function printPage() 
{
  window.print();
}

function sendPageUrl(subject, body)
{
  window.location = 'mailto: ?subject='+encodeURIComponent(subject)+'&body='+encodeURIComponent(body)+encodeURIComponent(window.location);
}


/* -------------------------------------------- */
/* -- Browser information --------------------- */
/* -------------------------------------------- */

Browser = new Object();
Browser.agt     = navigator.userAgent.toLowerCase();
Browser.is_ie	= ((Browser.agt.indexOf("msie") != -1) && (Browser.agt.indexOf("opera") == -1));


document.addLoadEvent = function(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

var JSTextFilter = {

  removeDiacritics: function (string) {

    string = string.replace(/á/g,'a');
    string = string.replace(/ä/g,'a');
    string = string.replace(/ą/g,'a');
    string = string.replace(/č/g,'c');
    string = string.replace(/ć/g,'c');
    string = string.replace(/ď/g,'d');
    string = string.replace(/é/g,'e');
    string = string.replace(/ě/g,'e');
    string = string.replace(/í/g,'i');
    string = string.replace(/ľ/g,'l');
    string = string.replace(/ĺ/g,'l');
    string = string.replace(/ł/g,'l');
    string = string.replace(/ň/g,'n');
    string = string.replace(/ń/g,'n');
    string = string.replace(/ó/g,'o');
    string = string.replace(/ô/g,'o');
    string = string.replace(/ő/g,'o');
    string = string.replace(/ŕ/g,'r');
    string = string.replace(/ř/g,'r');
    string = string.replace(/ś/g,'s');
    string = string.replace(/š/g,'s');
    string = string.replace(/š/g,'s');
    string = string.replace(/ť/g,'t');
    string = string.replace(/ú/g,'u');
    string = string.replace(/ü/g,'u');
    string = string.replace(/ž/g,'z');
    string = string.replace(/Á/g,'A');
    string = string.replace(/Č/g,'C');
    string = string.replace(/Ď/g,'D');
    string = string.replace(/É/g,'E');
    string = string.replace(/Ě/g,'E');
    string = string.replace(/Í/g,'I');
    string = string.replace(/Ľ/g,'L');
    string = string.replace(/Ĺ/g,'L');
    string = string.replace(/Ň/g,'N');
    string = string.replace(/Ó/g,'O');
    string = string.replace(/Ŕ/g,'R');
    string = string.replace(/Ř/g,'R');
    string = string.replace(/Š/g,'S');
    string = string.replace(/Ś/g,'S');
    string = string.replace(/Ť/g,'T');
    string = string.replace(/Ú/g,'U');
    string = string.replace(/Ž/g,'Z');

    return string;    
  }
}

function format_size (filesize)
{
    if (filesize >= 1073741824) {
        //filesize = number_format(filesize / 1073741824, 2, '.', '') + ' Gb';
        filesize = (filesize / 1073741824).toFixed(2) + ' Gb';
    } else if (filesize >= 1048576) {
        //filesize = number_format(filesize / 1048576, 2, '.', '') + ' Mb';
        filesize = (filesize / 1048576).toFixed(2) + ' Mb';
    } else if (filesize >= 1024) {
        //filesize = number_format(filesize / 1024, 0) + ' Kb';
        filesize = (filesize / 1024).toFixed(0) + ' Kb';
    } else {
        filesize = (filesize).toFixed(0) + ' bytes';
    }

    return filesize;
}

// Simulates PHP's date function
Date.prototype.format = function(format) {
    var str = '';
    for (var i = 0; i < format.length; i++) {
        var c = format.charAt(i);
        if (format.charAt(i - 1) == "\\") {
            str += c;
            continue;
        }

        switch (c) {
            //Day
            case 'd': str += (this.getDate() < 10 ? '0' : '') + this.getDate(); break;
            case 'D': str += App.i18n.dayNamesShort[this.getDay()]; break;
            case 'j': str += this.getDate();break;
            case 'l': str += App.i18n.dayNames[this.getDay()];break;
            case 'N': str += this.getDay() + 1;break;
            case 'S': str += (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th')));break;
            case 'w': str += this.getDay();break;
            case 'z': var d = new Date(this.getFullYear(),0,1); str += Math.ceil((this - d) / 86400000);break;
            //Week
            case 'W':  var d = new Date(this.getFullYear(), 0, 1); str +=  Math.ceil((((this - d) / 86400000) + d.getDay() + 1) / 7);break;
            //Month
            case 'F': str += App.i18n.monthNames[this.getMonth()];break;
            case 'm': str += (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1);break;
            case 'M': str += App.i18n.monthNamesShort[this.getMonth()];break;
            case 'n': str += this.getMonth() + 1;break;
            case 't': var d = new Date(); str += new Date(d.getFullYear(), d.getMonth(), 0).getDate();break;
            //year
            case 'L': var year = this.getFullYear(); str += (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0));break;
            case 'o': var d  = new Date(this.valueOf());  d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); str += d.getFullYear();break;
            case 'Y': str += this.getFullYear();break;
            case 'y': str += ('' + this.getFullYear()).substr(2);break;
            //time
            case 'a': str += (this.getHours() < 12 ? 'am' : 'pm');break;
            case 'A': str += (this.getHours() < 12 ? 'AM' : 'PM');break;
            case 'B': str += Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24);break;
            case 'g': str += (this.getHours() % 12 || 12);break;
            case 'G': str += this.getHours();break;
            case 'h': str += ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12);break;
            case 'H': str += ((this.getHours() < 10 ? '0' : '') + this.getHours());break;
            case 'i': str += ((this.getMinutes() < 10 ? '0' : '') + this.getMinutes());break;
            case 's': str += ((this.getSeconds() < 10 ? '0' : '') + this.getSeconds());break;
            case 'u': var m = this.getMilliseconds();str += ((m < 10 ? '00' : (m < 100 ? '0' : '')) + m);break;
            // Timezone
            case 'O': str += ((-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00');break;
            case 'P': str += ((-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':00');break;
            case 'T': var m = this.getMonth(); this.setMonth(0); var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); this.setMonth(m); str += result;break;
            case 'Z': str += (-this.getTimezoneOffset() * 60);break;
            // Full Date/Time
            case 'c': str += this.format("Y-m-d\\TH:i:sP");break;
            case 'r': str += this.toString();break;
            case 'U': str += this.getTime() / 1000;break;
            case '\\': str += '';break;
            default: str += c; break;
        }
    }
    return str;
};

String.prototype.reverse = function() {
    return this.split('').reverse().join('');
};

String.prototype.replaceAll = function(search, replace) {
    return this.replace(new RegExp(search, 'g'), replace);
};


function print_r(x, max, sep, l) {

	    l = l || 0;
	    max = max || 10;
	    sep = sep || ' ';

	    if (l > max) {
	        return "[WARNING: Too much recursion]\n";
	    }

	    var
	        i,
	        r = '',
	        t = typeof x,
	        tab = '';

	    if (x === null) {
	        r += "(null)\n";
	    } else if (t == 'object') {

	        l++;

	        for (i = 0; i < l; i++) {
	            tab += sep;
	        }

	        if (x && x.length) {
	            t = 'array';
	        }

	        r += '(' + t + ") :\n";

	        for (i in x) {
	            try {
	                r += tab + '[' + i + '] : ' + print_r(x[i], max, sep, (l + 1));
	            } catch(e) {
	                return "[ERROR: " + e + "]\n";
	            }
	        }

	    } else {

	        if (t == 'string') {
	            if (x == '') {
	                x = '(empty)';
	            }
	        }

	        r += '(' + t + ') ' + x + "\n";

	    }

	    return r;

	};



function empty (mixed_var) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philippe Baumann
    // +      input by: Onno Marsman
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: LH
    // +   improved by: Onno Marsman
    // +   improved by: Francesco
    // +   improved by: Marc Jansen
    // +   input by: Stoyan Kyosev (http://www.svest.org/)
    // *     example 1: empty(null);
    // *     returns 1: true
    // *     example 2: empty(undefined);
    // *     returns 2: true
    // *     example 3: empty([]);
    // *     returns 3: true
    // *     example 4: empty({});
    // *     returns 4: true
    // *     example 5: empty({'aFunc' : function () { alert('humpty'); } });
    // *     returns 5: false
    var key;

    if (mixed_var === "" || mixed_var === 0 || mixed_var === "0" || mixed_var === null || mixed_var === false || typeof mixed_var === 'undefined') {
        return true;
    }

    if (typeof mixed_var == 'object') {
        for (key in mixed_var) {
            return false;
        }
        return true;
    }

    return false;
}

function isset () {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: FremyCompany
    // +   improved by: Onno Marsman
    // +   improved by: RafaÅ‚ Kukawski
    // *     example 1: isset( undefined, true);
    // *     returns 1: false
    // *     example 2: isset( 'Kevin van Zonneveld' );
    // *     returns 2: true
    var a = arguments,
        l = a.length,
        i = 0,
        undef;

    if (l === 0) {
        throw new Error('Empty isset');
    }

    while (i !== l) {
        if (a[i] === undef || a[i] === null) {
            return false;
        }
        i++;
    }
    return true;
}

function round (value, precision, mode) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +    revised by: Onno Marsman
    // +      input by: Greenseed
    // +    revised by: T.Wild
    // +      input by: meo
    // +      input by: William
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Josep Sanz (http://www.ws3.es/)
    // +    revised by: RafaÅ‚ Kukawski (http://blog.kukawski.pl/)
    // %        note 1: Great work. Ideas for improvement:
    // %        note 1:  - code more compliant with developer guidelines
    // %        note 1:  - for implementing PHP constant arguments look at
    // %        note 1:  the pathinfo() function, it offers the greatest
    // %        note 1:  flexibility & compatibility possible
    // *     example 1: round(1241757, -3);
    // *     returns 1: 1242000
    // *     example 2: round(3.6);
    // *     returns 2: 4
    // *     example 3: round(2.835, 2);
    // *     returns 3: 2.84
    // *     example 4: round(1.1749999999999, 2);
    // *     returns 4: 1.17
    // *     example 5: round(58551.799999999996, 2);
    // *     returns 5: 58551.8
    var m, f, isHalf, sgn; // helper variables
    precision |= 0; // making sure precision is integer
    m = Math.pow(10, precision);
    value *= m;
    sgn = (value > 0) | -(value < 0); // sign of the number
    isHalf = value % 1 === 0.5 * sgn;
    f = Math.floor(value);

    if (isHalf) {
        switch (mode) {
        case 'PHP_ROUND_HALF_DOWN':
            value = f + (sgn < 0); // rounds .5 toward zero
            break;
        case 'PHP_ROUND_HALF_EVEN':
            value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
            break;
        case 'PHP_ROUND_HALF_ODD':
            value = f + !(f % 2); // rounds .5 towards the next odd integer
            break;
        default:
            value = f + (sgn > 0); // rounds .5 away from zero
        }
    }

    return (isHalf ? value : Math.round(value)) / m;
}


/*

function print_r (array, return_val) {
    // http://kevin.vanzonneveld.net
    // +   original by: Michael White (http://getsprink.com)
    // +   improved by: Ben Bryan
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +      improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: echo
    // *     example 1: print_r(1, true);
    // *     returns 1: 1
    var output = '',
        pad_char = ' ',
        pad_val = 4,
        d = this.window.document,
        getFuncName = function (fn) {
            var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
            if (!name) {
                return '(Anonymous)';
            }
            return name[1];
        },
        repeat_char = function (len, pad_char) {
            var str = '';
            for (var i = 0; i < len; i++) {
                str += pad_char;
            }
            return str;
        },
        formatArray = function (obj, cur_depth, pad_val, pad_char) {
            if (cur_depth > 0) {
                cur_depth++;
            }

            var base_pad = repeat_char(pad_val * cur_depth, pad_char);
            var thick_pad = repeat_char(pad_val * (cur_depth + 1), pad_char);
            var str = '';

            if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !== 'PHPJS_Resource') {
                str += 'Array\n' + base_pad + '(\n';
                for (var key in obj) {
                    if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
                        str += thick_pad + '[' + key + '] => ' + formatArray(obj[key], cur_depth + 1, pad_val, pad_char);
                    }
                    else {
                        str += thick_pad + '[' + key + '] => ' + obj[key] + '\n';
                    }
                }
                str += base_pad + ')\n';
            }
            else if (obj === null || obj === undefined) {
                str = '';
            }
            else { // for our "resource" class
                str = obj.toString();
            }

            return str;
        };

    output = formatArray(array, 0, pad_val, pad_char);

    if (return_val !== true) {
        if (d.body) {
            this.echo(output);
        }
        else {
            try {
                d = XULDocument; // We're in XUL, so appending as plain text won't work; trigger an error out of XUL
                this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">' + output + '</pre>');
            } catch (e) {
                this.echo(output); // Outputting as plain text may work in some plain XML
            }
        }
        return true;
    }
    return output;
}
*/


function in_array (needle, haystack, argStrict) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: vlado houba
    // +   input by: Billy
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);
    // *     returns 1: true
    // *     example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
    // *     returns 2: false
    // *     example 3: in_array(1, ['1', '2', '3']);
    // *     returns 3: true
    // *     example 3: in_array(1, ['1', '2', '3'], false);
    // *     returns 3: true
    // *     example 4: in_array(1, ['1', '2', '3'], true);
    // *     returns 4: false
    var key = '',
        strict = !! argStrict;

    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    } else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }

    return false;
}

/*
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function (obj, fromIndex) {
    if (fromIndex == null) {
        fromIndex = 0;
    } else if (fromIndex < 0) {
        fromIndex = Math.max(0, this.length + fromIndex);
    }
    for (var i = fromIndex, j = this.length; i < j; i++) {
        if (this[i] === obj)
            return i;
    }
    return -1;
  };
}
*/

