/**
 * @author lserrano
 * Generic SendToFriend Script v1.0
 * 
 * Notes:
 * IE 7 breaks getElementById: http://remysharp.com/2007/02/10/ie-7-breaks-getelementbyid/
 * XMLHttpRequest: http://www.javascripter.net/faq/xmlhttpr.htm
 * setAttribute('style', ...) workaround for IE: http://www.peterbe.com/plog/setAttribute-style-IE
 */

function EnviarAmigo () {
    /** Properties & Fields **/
    // Labels    
    /* string */ this.fromNameText = 'Tu nombre';
    /* string */this.fromEmailText = 'Tu correo';
    /* string */this.toNameText = 'Nombre del destinatario';
    /* string */this.toEmailText = 'Correo del destinatario';
    /* string */this.commentsFieldText = 'Comentario';
    /* string */this.sendButtonText = 'Enviar';
    /* string */this.cancelButtonText = 'Cancelar';
    /* string */this.invalidEmailText = 'El e-mail introducido no es correcto!';
	/* string */this.template='';
				this.width='250px';
				this.heigth='400px';
    // Messages
    /* string */this.sendingErrorMessage = 'Ha ocurrido un error enviando el correo.\nDisculpe las molestias.';
    
    // Ajax messages
    /* string */this.lastResponse = '';
    
    // Configuration
    /* string */this.URL = 'test.html';
    /* bool */this.validateEmailAdresses = true;
    /* bool */this.addCommentsField = true;
    
    // Private variables
    /* bool */this.initialized = false;
    /* object */this.GlobalAjaxObject = null;    
};

EnviarAmigo.prototype.initialize = function() {
    try {
        this.addElements();
        this.GlobalAjaxObject = this._createAjaxObj();
        if (this.GlobalAjaxObject) {
            this.initialized = true;
            return (true);
        } else {
            return (false);
        }
    } catch (e) {
        alert (e.message);
        return (false);
    }
};

EnviarAmigo.prototype.addElements = function () {
    
    if (!this.find('EnviarAmigobackgroundlayer')) {
		// Background layer
		var lBackgroundLayer = document.createElement('div');
		lBackgroundLayer.setAttribute('id', 'EnviarAmigobackgroundlayer');
		this._setStyle(lBackgroundLayer, 'position:fixed; top:0; left:0; right:0; bottom:0; background-color: #CCCCCC; -moz-opacity:0.6; filter:alpha(opacity=60);');
		
		// Form layer
		var lFormLayer = document.createElement('div');
		lFormLayer.setAttribute('id', 'EnviarAmigoformlayer');
		//TODO: create proper css class
		if (this.template != "") {
			this._setStyle(lFormLayer, 'font-size: 12px; text-align: center; width:'+this.width+'; height:'+this.heigth+'; padding: 0px; background-color: #FFFFFF;z-index:10000;');
			this.centerDiv(lFormLayer);
			this.iFrame = document.createElement('iframe');
			this.iFrameId = 'LinkLayerViewerIFrame' + utils.evt.generateGuid();
			this.iFrame.setAttribute('id', this.iFrameId);
			this.iFrame.setAttribute('src', this.template);
			this.iFrame.setAttribute('frameBorder', 0);	
			this.iFrame.setAttribute('scrolling', 'no');			
			this.iFrame.style.height=this.heigth;
			this.iFrame.style.width=this.width;
			lFormLayer.appendChild(this.iFrame)
		}
	    else{
			this._setStyle(lFormLayer, 'font-size: 12px; text-align: center; width:'+this.width+'; height:'+this.heigth+'; padding: 20px; background-color: #FFFFFF; border-width: 2px; border-style: solid;  border-color: #000000;');
			this.centerDiv(lFormLayer);
		
			lFormLayer.innerHTML = this.createStandardForm();
		}        
        // Add background...
        document.body.appendChild (lBackgroundLayer);            
        // Add form...
        document.body.appendChild (lFormLayer); 

        // Set Up Events
        this.setStandardFormEvents();
        
        // Set focus to standard form
        this.setFocusToStandardForm();
    }
};

EnviarAmigo.prototype.removeElements = function () {
    var lVictimLayer;
    // Remove Form
    lVictimLayer = this.find('EnviarAmigoformlayer');
    if (lVictimLayer) { 
        document.body.removeChild (lVictimLayer);
    }        
    // Remove Background 
    // A fancy fade-out would be perfect ;)
    lVictimLayer = this.find('EnviarAmigobackgroundlayer');
    if (lVictimLayer) { 
        document.body.removeChild (lVictimLayer);
    }
    this.initialized = false;
};

EnviarAmigo.prototype.readFormTemplate = function () {/* Not *yet* implemented */
    // http://www.javascripter.net/faq/xmlhttpr.htm
};

EnviarAmigo.prototype.createStandardForm = function () {
    var lLabelClass = 'classSTFLabel';
    var lButtonRowClass = 'classSTFButton';
    var lFormContent = '';
    lFormContent += '<form id="EnviarAmigo_form">\n';
    lFormContent += this.createDiv(this.fromNameText, null, lLabelClass);
    lFormContent += this.createDiv('<input type="text" id="EnviarAmigo_fromName" />');
    lFormContent += this.createDiv(this.fromEmailText, null, lLabelClass);
    lFormContent += this.createDiv('<input type="text" id="EnviarAmigo_fromEmail" />');
    lFormContent += this.createDiv(this.toNameText, null, lLabelClass);
    lFormContent += this.createDiv('<input type="text" id="EnviarAmigo_toName" />');
    lFormContent += this.createDiv(this.toEmailText, null, lLabelClass);
    lFormContent += this.createDiv('<input type="text" id="EnviarAmigo_toEmail" />');
    if (this.addCommentsField) {
        lFormContent += this.createDiv(this.commentsFieldText, null, lLabelClass);
        lFormContent += this.createDiv('<textarea id="EnviarAmigo_commentsField"></textarea>');
    }
    lFormContent += this.createDiv('<br /><input type="submit" id="EnviarAmigo_submit" value=' + this.sendButtonText + ' />&nbsp;<input type="button" id="EnviarAmigo_cancel" value=' + this.cancelButtonText + ' />', null, lButtonRowClass);
    lFormContent +  '</form>\n';
    lFormContent += '\n';
    return (lFormContent);
};

/**
* Devuelve el QueryString de una URL en formato clave-valor
*/
EnviarAmigo.prototype.setStandardFormEvents = function () {
	
	var lCancelButton = this.find('EnviarAmigo_cancel');
	var lFormAction = this.find('EnviarAmigo_form');
	
	if (lCancelButton) lCancelButton.onclick = this.createDelegate (this, this.removeElements);
	if (lFormAction) lFormAction.onsubmit = this.createDelegate (this, this.sendMail);
}

EnviarAmigo.prototype.setFocusToStandardForm = function() {
    var lFirstField = this.find('EnviarAmigo_fromName');
    if (lFirstField) {
        lFirstField.focus();
        lFirstField.select();
    }        
};

/**
* Checks e-mail address, returns boolean
* @param {Object} aFieldName
* @return {bool}
*/
EnviarAmigo.prototype.checkEmailAddress = function(aFieldName /* object */) {
    if (this.validateEmailAdresses) {
        var field = this.find(aFieldName);
        var validEmail = field.value.match(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.gov)|(\.org)|(\.info)|(\.cat)|(\.pro)|(\..{2,2}))$)\b/gi);
        if (validEmail) {
        	return true;
        }
        else 
        {
            alert(this.invalidEmailText);
            field.focus();
            field.select();
            return false;
        }
    } else return (true);
};

EnviarAmigo.prototype.sendMail = function() {
    var lValidations = false;
    if (this.checkEmailAddress('EnviarAmigo_fromEmail')) {
        if (this.checkEmailAddress('EnviarAmigo_toEmail')) {
            // Do stuff
            var lUrl = this.Url;
            lUrl += '?fromName=' + this.readField('EnviarAmigo_fromName', true);
            lUrl += '&fromEmail=' + this.readField('EnviarAmigo_fromEmail', true);
            lUrl += '&toName=' + this.readField('EnviarAmigo_toName', true);
            lUrl += '&toEmail=' + this.readField('EnviarAmigo_toEmail', true);
            lUrl += '&URL=' + this.getEscapedSelfLocation();
            alert (lUrl);
            try {
            /**var lResponse = this._send(lUrl);
            if (lResponse)
                alert('[Enviado: ]' + lResponse);
            else
                alert (this.sendingErrorMessage);
            */
           } catch (e) {
                alert (this.sendingErrorMessage);
                lValidations = true;
           }
        }            
    } 
    if (lValidations) this.removeElements();
};

/* DOM & String Methods */
EnviarAmigo.prototype.createDiv = function (aContent /* string */, aDivId /* string */, aClassName /* string */) {
    if (document.all) { // IE
        var lNewDiv = document.createElement('div');
        if (aDivId) lNewDiv.setAttribute('id', aDivId);
        if (aClassName) lNewDiv.setAttribute('class', aClassName);
        lNewDiv.innerHTML = aContent; 
        return lNewDiv.outerHTML;
    } else { // Mozilla
        var lNewDiv = '<div ';
        if (aDivId) lNewDiv +='id="' + aDivId + '" ';
        if (aClassName) lNewDiv +='class="' + aClassName + '" ';
        lNewDiv += '>' + aContent + '</div>';
        return(lNewDiv);
    }
};

EnviarAmigo.prototype.centerDiv = function (aDiv) {
    if (aDiv) {
        var lDivWidth;
        var lDivHeight;
        
        if (aDiv.offsetHeight) lDivHeight = aDiv.offsetHeight;
        else if (aDiv.style.height) lDivHeight = aDiv.style.height.replace('px','');

        if (aDiv.offsetWidth) lDivWidth = aDiv.offsetWidth;
        else if (aDiv.style.width) lDivWidth = aDiv.style.width.replace('px','');

        var lCenteredX = parseInt((window.screen.availWidth / 2) - (lDivWidth /2));
        var lCenteredY = parseInt((window.screen.availHeight / 2) - (lDivHeight));        

        aDiv.style.position = 'fixed';
        aDiv.style.top = lCenteredY + 'px';
        aDiv.style.left = lCenteredX + 'px';
    }
    
};

EnviarAmigo.prototype.find = function(objectName) {
   return (document.getElementById(objectName)); 
};

EnviarAmigo.prototype.readField = function(aFieldName /* string */, aEscaped /* boolean */) {
    var lField = this.find (aFieldName);
    if (lField) {
        var lValue = this.trim(lField.value);
        if (!aEscaped) 
            return (lValue);
        else return (escape(lValue)); 
    } else return null;
};    

EnviarAmigo.prototype.trim = function (str, chars) {
    return this._ltrim(this._rtrim(str, chars), chars);
};    

EnviarAmigo.prototype._ltrim = function (str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
};    

EnviarAmigo.prototype._rtrim = function (str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
};  

EnviarAmigo.prototype.getEscapedSelfLocation = function () {
    return (escape(window.location.href));
};

/* Ajax Methods */
EnviarAmigo.prototype._createAjaxObj = function() {
    var lAjaxObj = null;    
    if (typeof XMLHttpRequest != 'undefined') 
    {
        lAjaxObj = new XMLHttpRequest();
    } else {
        try {
            lAjaxObj = new ActiveXObject("Msxml2.XMLHTTP");
        } 
        catch (e) {
            // Last choice
            try { 
                lAjaxObj = new ActiveXObject("Microsoft.XMLHTTP");    
            } catch (e) { }
        }
    }        
    return lAjaxObj;
};

EnviarAmigo.prototype._send = function(aURL /* string */) {
    if (this.GlobalAjaxObject) {
        this.GlobalAjaxObject.open("GET", aUrl, false);
        if (this.GlobalAjaxObject.status == 200) {
                var lResponse = document.createElement("div");
                lResponse.innerHTML = this.GlobalAjaxObject.responseText;
                return lResponse.childNodes;
        }
        else return (null);   
    }        
};

/* IE Hacks */
EnviarAmigo.prototype._rzCC = function(s /* string */) {
    for(var exp=/-([a-z])/; 
        exp.test(s); 
        s=s.replace(exp,RegExp.$1.toUpperCase()));
    return s;
};

EnviarAmigo.prototype._setStyle = function (aElement /* object */, aDeclaration /* CSS Declaration */) {
    try {     
        if (aElement) {
            aDeclaration = aDeclaration.replace(/\s+/g,''); // remove all white spaces
            if (document.all) { // IE Hack
                if (aDeclaration.charAt(aDeclaration.length-1)==';')
                    aDeclaration = aDeclaration.slice(0, -1);
                var k, v;
                var splitted = aDeclaration.split(';');
                for (var i=0, len=splitted.length; i<len; i++) {
                    k = this._rzCC(splitted[i].split(':')[0]);
                    v = splitted[i].split(':')[1];
                    eval("aElement.style."+k+"='"+v+"'");
                }
                return (true);
            } else { // The clean way
                aElement.setAttribute ('style', aDeclaration);
                return (true);
            }
        }
    } catch (e) {
        return (false);
    }
}

/* Event Handling */

/**
 * Curry delegate function. [included here for testing purposes. use utils.evt.createDelegate!]
 * @param {Object} aInstance : Object context method.
 * @param {Function} aFunction : Function to be called.
 */
EnviarAmigo.prototype.createDelegate = function(aInstance, aFunction)
{
    return function()
    {
        return aFunction.apply(aInstance, arguments);
    };
}