

var NOW = new Date().getTime();

Object.class2type = {
                '[object Array]': "array",
                '[object Boolean]': "boolean",
                '[object Date]': "date",
                '[object Function]': "function",
                '[object Number]': "number",
                '[object Object]': "object",
                '[object RegExp]': "regexp",
                '[object String]': "string"
};

Object.extend				= function( destination, source ) {

		for (var property in source) {

			destination[property] = source[property];
		}
        return destination;
};

Object.Type					= function ( obj ) {
	
		return obj == null
            ? String( obj )
            : obj.nodeType && obj.nodeType === 1
            	? "element"
            	: Object.class2type[ Object.prototype.toString.call(obj) ] || "object";
};

Object.isNumber 			= function ( obj ) {

		return Object.Type(obj) === "number";
};

Object.isString				= function ( obj ) {

		return Object.Type(obj) === "string";
};

Object.isArray 				= function ( obj ) {

		return Object.Type(obj) === "array";
};

Object.isFunction 			= function ( obj ) {

		return Object.Type(obj) === "function";
};

Object.isUndefined 			= function ( obj ) {

		return typeof obj === "undefined";
};

Object.isNull				= function ( obj ) {

		return Object.Type(obj) === "null";
};
    
Object.isElement			= function ( obj ) {

		return obj && obj.nodeType === 1;
};

Object.isWindow				= function ( obj ) {

		return obj && Object.Type(obj) === "object" && "setInterval" in obj;
};

Object.isEmptyObject		= function ( obj ) {

		if(!Object.Type(obj) === "object") return false;

        for ( var name in obj ) {
            return false;
        }
        return true;
};

Object.clone				= function (object) {

		return Object.extend({ }, object);
};

Object.emptyFunction		= function() {};

//	Object.class2type			// pomocný objekt metody Object.Type()
//	Object.extend()				// rozšíří objekt o vlastnosti a metody jiného objektu
//	Object.Type()				// vrací řetězcovou reprezentaci typu objektu
//	Object.isNumber()			// ověří, zda-li je objekt číslem
//	Object.isString()			// ověří, zda-li je objekt řetězcem
//	Object.isArray()			// ověří, zda-li je objekt polem
//	Object.isFunction()			// ověří, zda-li je objekt funkcí
//	Object.isUndefined()		// ověří, zda-li má objekt hodnotu undefined
//	Object.isNull()		// ověří, zda-li má objekt hodnotu null
//	Object.isElement()		// ověří, zda-li je objekt Elementem (nodeType === 1)
//	Object.isWindow()			// ověří, zda-li je objekt globální objekt window
//	Object.isEmptyObject()		// ověří, zda-li je objekt prázdný
//	Object.clone()				// klonuje vlastnosti a metody objektu
//	Object.emptyFunction()		// prázdná funkce


Array.prototype.first					= function ( ) {

		return this[0];
};

Array.prototype.last					= function ( ) {

		return this[this.length - 1];
};

Array.prototype.clear					= function ( ) {

		this.length = 0;
        return this;
};

Array.prototype.trim					= function ( ) {

		for(var i = 0, length = this.length; i < length; i++) {
			
				if(Object.Type(this[i]) === "string") {
					this[i] = this[i].trim();
				}
		}
	
		return this;
};

Array.prototype.indexOf = Array.prototype.indexOf ||
										function ( searchElement, fromIndex ) {

		var length = this.length;

        fromIndex = Number(fromIndex) || 0;

        fromIndex = (fromIndex < 0)
        	? Math.ceil(fromIndex)
            : Math.floor(fromIndex);

        if (fromIndex < 0) fromIndex += length;

        for (; fromIndex < length; fromIndex++) {
        	if (fromIndex in this && this[fromIndex] === searchElement)
        		return fromIndex;
            }
        return -1;
};

Array.prototype.lastIndexOf = Array.prototype.lastIndexOf ||
										function ( searchElement, fromIndex ) {

		var length = this.length;

        fromIndex = Number(fromIndex);

        if (isNaN(fromIndex)) {
        	fromIndex = length - 1;
        }
        else {
        	fromIndex = (fromIndex < 0)
            	? Math.ceil(fromIndex)
                : Math.floor(fromIndex);

	        if (fromIndex < 0) fromIndex += length;
	
	        else if (fromIndex >= length) fromIndex = length - 1;
        }

        for (; fromIndex > -1; fromIndex--) {
        	if (fromIndex in this && this[fromIndex] === searchElement)
        		return fromIndex;
            }
        return -1;
};

Array.prototype.sortCorrect				= function ( ) {

		// seřazení abecedně
		this.sort();

		// správné seřazení číselných hodnot
		var compare = function(value1, value2) {
				if( value1 < value2 ) return -1;
                if( value1 > value2 ) return 1;
                return 0;
        };
		this.sort(compare);
        return this;
};

Array.prototype.sortNumber				= function ( ) {

		return this.sort( function (a,b) {return a-b;} );
};

Array.prototype.clone					= function ( ) {

		return this.slice();
};

Array.prototype.remove					= function () {

	var argsLength = arguments.length,
    	returnArray = [];

        for( var length = this.length, i = 0; i < length; i++ ) {
        	for( var x = 0; x < argsLength; x++ ) {
        		if(arguments[x] === this[i]) {
        			this.splice(i, 1);
                    --i;
//                  if(!returnArray.indexOf(arguments[x])) // Přidané podmínky zabrání duplicitnímu vložení hodnoty, která je z pole odstraněna vícekrát
                    returnArray.push(arguments[x]);
                    break;
                }
            }
        }
        return returnArray;
};


//	Array.prototype.first()				// Vrací první prvek pole nebo undefined
//	Array.prototype.last()				// Vrací poslední prvek pole nebo undefine
//	Array.prototype.clear()				// Vrací prázdné (vymazané) pole
//	Array.prototype.trim()				// Na prvních pole, jež jsou řetězcem, zavolá metodu trim()
//	Array.prototype.indexOf()			// Vrací index prvního výskytu prvku v poli nebo -1
//	Array.prototype.lastIndexOf()		// Vrací index posledního výskytu prvku v poli nebo -1
//	Array.prototype.sortCorrect()		// Seřadí správně (i včetně čísel) prvky v poli 
//	Array.prototype.sortNumber()		// Metoda určená pro seřazení pole pouze s číselnými hodnotami
//	Array.prototype.clone()				// Vrací duplikát pole, původní pole neporuší
//	Array.prototype.remove()			// Odstraní prvky z pole




Date.DAYNAMES	= ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"];
Date.MONTHNAMES = ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"];

Date.prototype.copy					= function ( ) {
		/**
         * Vytvoří­ kopii datumu.
         * Example:
         * var old_date = new Date();
         * var new_copy = old_date.copy();
         */
		return new Date (this.getTime());
};

Date.prototype.getDayName			= function ( ) {

		return this.DAYNAMES[this.getDay()];
};

Date.prototype.getMonthName			= function ( ) {

		return this.MONTHNAMES[this.getMonth()];
};

Date.prototype.getDayOfYear			= function () {

	var numberOfPreviousMonths,
    	currentYear = this.getFullYear(),
        days = 0;

        numberOfPreviousMonths = this.getMonth(); // počet předcházejících měsíců

        for(var i=0; i<numberOfPreviousMonths; i++) {
            days += (new Date(currentYear,(i+1),0).getDate());
        }
        return (days + this.getDate());
};

Date.prototype.lastDay				= function ( ) {
        /**
         * Vrací číselnou reprezentaci posledního dne v měsíci.
         * Jinak řečeno vrací počet dnů v daném měsíci.
         */
        var d = new Date(this.getFullYear(), this.getMonth() + 1, 0);
        return d.getDate();
};

Date.prototype.to24HourTimeString	= function ( ) {
        /**
         * Vrací čas ve formátu hh:mm:ss
         */
        var h = "0" + this.getHours(),
            m = "0" + this.getMinutes(),
            s = "0" + this.getSeconds();

        return h.slice(-2) + ":" + m.slice(-2) + ":" + s.slice(-2);
};

Date.prototype.addDays				= function ( numberOfDays ) {
        /**
         * Přičte k datumu zadaný počet dnů.
         * Je-li argument záporný, příslušný počet dnů odečte.
         */
        if(typeof numberOfDays != 'number' || numberOfDays == 0)
            return this;

        this.setDate( this.getDate() + numberOfDays );
        return this;
};

Date.prototype.addMonths			= function ( numberOfMonths ) {
        /**
         * Přičte k datumu zadaný počet měsíců.
         * Je-li argument záporný, příslušný počet měsíců odečte.
         */
        if(typeof numberOfMonths != 'number' || numberOfMonths == 0)
            return this;

        this.setMonth(this.getMonth() + numberOfMonths);
        return this;
};

Date.prototype.addYears				= function ( numberOfYears ) {
        /**
         * Přičte k datumu zadaný počet roků.
         * Je-li argument záporný, příslušný počet roků odečte.
         */
        if(typeof numberOfYears != 'number' || numberOfYears == 0)
            return this;

        var m = this.getMonth();
        this.setFullYear(this.getFullYear() + numberOfYears);

        // ošetření u přestupných let
        if (m < this.getMonth()) {
            this.setDate(0);
        }
        return this;
};

Date.prototype.getDaysBetween		= function ( date ) {

        // počet milisekund v jednom dnu
        var ONE_DAY = ( 1000 * 60 * 60 * 24 );

        // převedení datumu na milisekundy
        var date1_ms = this.getTime();
        var date2_ms = date.getTime();

        // výpočet rozdílu v milisekundách
        var difference_ms = Math.abs(date1_ms - date2_ms);

        // převedení zpět na dny a vrácení počtu dnů
        return Math.round(difference_ms/ONE_DAY);
};

//	Date.prototype.DAYNAMES					// Seznam českých názvů dnů
//	Date.prototype.MONTHNAMES				// Seznam českých názvů měsíců
//	Date.prototype.copy()					// Vytvoří kopii datumu a zruší provázání
//	Date.prototype.getDayName()				// Vrací řetězcovou reprezentaci dne
//	Date.prototype.getMonthName()			// Vrací řetězcovou reprezentaci měsíce
//	Date.prototype.getDayOfYear()			// Vrací číselnou reprezentaci dne v příslušném roce
//	Date.prototype.lastDay()				// Vrací číselnou reprezentaci posledního dne v měsíci (počet dnů daného měsíce)
//	Date.prototype.to24HourTimeString()		// Vrací čas ve formátu hh:mm:ss
//	Date.prototype.addDays()				// Přidá k datumu zadaný počet dnů
//	Date.prototype.addMonths()				// Přidá k datumu zadaný počet měsíců
//	Date.prototype.addYears()				// Přidá k datumu zadaný počet roků
//	Date.prototype.getDaysBetween()			// Vrací počet dnů mezi dvěma daty


Function.prototype.delay 				= function ( timeout ) {

	var that = this,
    	args = Array.prototype.slice.call(arguments, 1);

        timeout = timeout * 1000;

        return window.setTimeout(function() {
            return that.apply(that, args);
        }, timeout);
};

//	Function.prototype.delay()				// Spustí funkci opožděně


String.prototype.compareWithArrayValues	= function ( array ) {
	
		for(var i = 0, length = array.length; i < length; i++) {
			
				if(this.toString() == array[i]) return true;
		}
		return false;
};

String.prototype.listIndexOf 			= function ( substring ) {

	var positions = [],
    	pos = this.indexOf(substring);

        while( pos > -1 ) {
            positions.push(pos);
            pos = this.indexOf(substring, pos + 1);
        }

        return positions;
};

String.prototype.escapeHTML 			= function ( ) {

		return this.replace(/[<>"&]/g, function(match, pos, originalText)
            {
                switch(match) {
                    case "<":
                        return "&lt;";
                    case ">":
                        return "&gt;";
                    case "&":
                        return "&amp;";
                    case "\"":
                        return "&quot;";
                }
            });
};

String.prototype.unescapeHTML 			= function ( ) {

		return this.replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&').replace(/&quot;/g,'\"');
};

String.prototype.trim 					= function ( ) {

		return this.replace(/^\s+/, '').replace(/\s+$/, '');
};

String.prototype.trimLeft				= function ( ) {

		return this.replace(/^\s+/, '');
};

String.prototype.trimRight				= function ( ) {

		return this.replace(/\s+$/, '');
};

String.prototype.camelize				= function ( ) {

		return this.replace(/-+(.)?/g, function(match, chr) {
            return chr ? chr.toUpperCase() : '';
        });
};

String.prototype.isBlank				= function ( ) {

		return /^\s*$/.test(this);
};

String.prototype.isEmpty				= function ( ) {

		return this == '';
};

String.prototype.include				= function ( substring ) {

		return this.indexOf(substring) > -1;
};

String.prototype.startsWith				= function ( substring ) {

		return this.lastIndexOf(substring, 0) === 0;
};

String.prototype.endsWith				= function ( substring ) {

		var d = this.length - substring.length;
        return d >= 0 && this.indexOf(substring, d) === d;
};

String.prototype.parseInt_				= function ( ) {

		return parseInt(this);
};

String.prototype.parseFloat_			= function ( ) {

		return parseFloat(this);
};

String.prototype.truncate				= function (length, endSubstring) {

		length = length || 30;
        endSubstring = !endSubstring ? '...' : endSubstring;
        
        return this.length > length
            ? this.slice(0, length - endSubstring.length) + endSubstring
            : String(this);
};

String.prototype.toArray				= function ( separator ) {

		return this.split(separator);
};


//	String.prototype.compareWithArrayValues() // Vrací true, pokud je řetězec shodný s některým prvkem v poli
//	String.prototype.listIndexOf()			// Vrací pole se seznamem všech pozic výskytů podřetězců v řetězci
//	String.prototype.escapeHTML()			// Zakóduje znaky < > & " pomocí entit
//	String.prototype.unescapeHTML()			// Dekóduje znaky < > & " pomocí entit
//	String.prototype.trim()					// Odstraní všehny počáteční a koncové mezery v řetězci
//	String.prototype.trimLeft()				// Odstraní všechny počáteční mezery v řetězci
//	String.prototype.trimRight()			// Odstraní všechny koncové mezery v řetězci
//	String.prototype.camelize()				// Převede řetězec oddělený pomlčkami na CamalCase ekvivalent
//	String.prototype.isBlank()				// Ověří, zda-li je řetězec prázdný nebo obsahuje pouze bílé znaky
//	String.prototype.isEmpty()				// Ověří, zda-li je řetězec prázdný a neobsahuje žádné bílé znaky
//	String.prototype.include()				// Ověří, zda řetězec obsahuje daný podřetězec
//	String.prototype.startsWith()			// Ověří, zda-li řetězec začíná podřetězcem
//	String.prototype.endsWith()				// Ověří, zda-li řetězec končí podřetězcem
//	String.prototype.parseInt_()			// Ekvivalent k window.parseInt()
//	String.prototype.parseFloat_()			// Ekvivalent k window.parseFloat()
//	String.prototype.truncate()				// Zkrátí řetězec na danou délku
//	String.prototype.toArray()				// Převede řetězec na pole na základě předaného oddělovače



Math.selectFrom					= function ( lowerValue, upperValue) {

		var choices = upperValue - lowerValue + 1;
        return Math.floor(Math.random() * choices + lowerValue);
};

//	Math.selectFrom()			// Vrací náhodné celé číslo v daném rozsahu




