/**
 * Класс предоставляющий набор вспомогательных ф-ций
 * @base EventDispatcher
 * @author Denis Panaskin <goliathdp@gmail.com>
 */
function Tools()
{
	this.listener = new Array();
}// end Tools

Tools.prototype = new EventDispatcher();

/**
 * Экземпляр Tools класса
 * @type Tools
 * @private
 */
Tools.instance = null;

/**
 * Получаем доступ к экземпляру класса
 * @return Tools
 */
Tools.getInstance = function()
{
	if(Tools.instance == null)
		Tools.instance = new Tools();
	return Tools.instance;
}// end getInstance


/**
 * Тест на проверку заполнения полей форм. Возвращает true если 
 * все поля заполненны корректоно
 * @param ссылка на форму
 * @return Bookean
 */
Tools.prototype.isFieldsSuccess = function(form)
{
	if(form.elements==null || form.elements.length==0)// Если форма пустая
	{
		throw "Festi Tools.js: Not a single element is found in a form \""+form.name+"\"";
		return false;
	}
	
	var isSuccess = true;
	
	for(i=0; i<form.elements.length; i++)
	{
		var type = form.elements[i].type;

		if(type != "radio" && type != "button" &&  type != "submit" && type!="checkbox")
		{
			if(form.elements[i].name==null)
				continue;
				
			if(form.elements[i].getAttribute("fieldTest")!=null)
			{
				switch(form.elements[i].getAttribute("fieldTest"))
				{
					case "isEmpty":
						if(this.isFieldEmpty(form.elements[i]))
						{
							var event = new Object();
							event.name = form.elements[i].name;
							this.dispatchEvent(Event.EMPTY, event);
							isSuccess = false;
							form.elements[i].focus();
							form.elements[i].select();
						}
						break;
					
					case "Email":
						if(!this.isEmailCorrect(form.elements[i]))
						{
							var event = new Object();
							event.name = form.elements[i].name;
							this.dispatchEvent(Event.EMPTY, event);
							isSuccess = false;
							form.elements[i].focus();
							form.elements[i].select();
						}
						break;
				}
				
			}
		}
	}
	
	if(isSuccess)
		return true;
	
	var event = new Object();
	event.name = form.name;
	this.dispatchEvent(Event.NOT_SUCCESS, event);
	return false;
}// end isFieldsSuccess

/**
 * Проверка на пустоту поля. Возвращает true если поле пустое
 * @param field поле формы
 * @return Boolean
 */
Tools.prototype.isFieldEmpty = function(field)
{
	if(field.value.length==0)
		return true;
	return false;
}

Tools.prototype.isEmailCorrect = function(field)
{
	if(field.value =='')
		return false;
		
	var eSimbol = new Array(), 
	flag = 0;
	eSimbol[0] = '`'; eSimbol[1] = '~'; eSimbol[2] ='!'; eSimbol[3] = '#'; eSimbol[4] = '"'; eSimbol[5] = '№'; eSimbol[6] = '$'; eSimbol[7] =';';
	eSimbol[8] = '%'; eSimbol[9] ='^'; eSimbol[10] = ':'; eSimbol[11] = '&'; eSimbol[12] = '?'; eSimbol[13] = '*'; eSimbol[14] = '(';
	eSimbol[15] = ')'; eSimbol[16] = '_'; eSimbol[17] = '+'; eSimbol[18] = '|'; eSimbol[19] = ' '; eSimbol[20] = '/'; eSimbol[21] = "'"; eSimbol[22] = '{';
	eSimbol[23] = '}'; eSimbol[24] = '['; eSimbol[25] = ']'; eSimbol[26] = ','; eSimbol[27] = '<'; eSimbol[28] = ' >';
	
	//Наличие собаки и проверк на отсутствие точек до знака @
	if(field.value.indexOf('@') ==-1)
		return false;
	if(field.value.lastIndexOf( '.' , field.value.indexOf('@')) != -1)
		return false;
			
	var i , j, stringErrors = '';  
	for(i = 0; i<=field.value.length - 1; i++)
	{
		for(j= 0; j <= eSimbol.length - 1; j++)
		{
			if(field.value.charAt(i) == eSimbol[j] )
				return false;
		}
	}
	
	return true;
}

/**
* Получаем ширину видимой области экрана.
* @see #getClientHeight
* @return Integer
*/
Tools.getClientWidth = function()
{
	return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientWidth:document.body.clientWidth;
}// end getClientWidth

/**
* Возвращает высоту видимой области.
* @see #getClientWidth
* @return Integer
*/
Tools.getClientHeight = function()
{
  return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientHeight:document.body.clientHeight;
}// end getClientHeight

Tools.getScrol = function() {
	var yPos = 0;
    if (self.pageYOffset) {
    	yPos = self.pageYOffset;
     } else if (document.documentElement && document.documentElement.scrollTop){
           yPos = document.documentElement.scrollTop;
       } else if (document.body) {
           yPos = document.body.scrollTop;
       }
       return yPos; 
}

/**
 * Получаем абсолютную позицию елемента, с учетом вложоности.
 * @param String objId Идентификатор елемента
 */
Tools.getObjectPosition = function(objId) 
{
	var obj = document.getElementById(objId);
    var offsetLeft = 0;
    var offsetTop = 0;
	
	/** Обходим дерево родительских елементов */
	while(obj) 
	{
      offsetLeft += obj.offsetLeft;
      offsetTop += obj.offsetTop;
      obj = obj.offsetParent;
    }// end while

	return {'top':offsetTop, 'left':offsetLeft};
}// end getPos

/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}
	
	
	