com_htmli_ui_Source.cache = false; 
com_htmli_forms_Input.dontDispatchChangeEvent = true;

function PRD() {
    this.timeoutSeconds = 10;
    this.dateRegExp = '\\d\\d/\\d\\d/\\d\\d\\d\\d';
    this.dateTimeRegExp = '\\d\\d/\\d\\d/\\d\\d\\d\\d \\d\\d:\\d\\d';    
    this.timeRegExp = '\\d\\d:\\d\\d';    
    this.timeQuantityRegExp = '\\d\\d:\\d\\d';        
    this.timeRangeRegExp = '\\d\\d:\\d\\d-\\d\\d:\\d\\d';            
}

window.onerror = function(message, url, line) {
	if (top.problemsHandler) {
		return top.problemsHandler(message, url, line);
	}
};


PRD.SERVER_PATH = '../xml/';
//PRD.SERVER_PATH = '../mockserver/';
//PRD.SERVER_PATH = '../ideservices/';

PRD.prototype.store = function(me, handler, isAsync, entity) {
    this.apply(me, function(key) {
    	if (handler) {
	        handler(key);
		} 
		if (isAsync) {
			prd.startAsyncConsole(me.getContainer(), key, entity);
		}
    });
}

PRD.prototype.cancel = function(me) {
    var container = me.getContainer();
    container.getElementById('window').close();
    container.close();
}

var c;
/********************** validations ***************************/

PRD.validations = [];
PRD.validations['required'] = function(obj) { return obj.value && (obj.tagName.toLowerCase() != 'select' || obj.value != '0') ? null : (obj.title + ' es requerido'); };
PRD.validations['date'] = function(obj) { return obj.value == '' || obj.value.match(prd.dateRegExp) ? null : (obj.title + ' es fecha'); };
PRD.validations['datetime'] = function(obj) { return obj.value == '' || obj.value.match(prd.dateTimeRegExp) ? null : (obj.title + ' es fecha-hora'); };
PRD.validations['time'] = function(obj) { return obj.value == '' || obj.value.match(prd.timeRegExp) ? null : (obj.title + ' es hora'); };
PRD.validations['timequantity'] = function(obj) { return obj.value == '' || obj.value.match(prd.timeQuantityRegExp) ? null : (obj.title + ' es cantidad de tiempo'); };
PRD.validations['timerange'] = function(obj) { return obj.value == '' || obj.value.match(prd.timeRangeRegExp) ? null : (obj.title + ' es rango de tiempo'); };
PRD.validations['email'] = function(obj) { return obj.value == '' || obj.value.match(/^([a-zA-Z0-9_\.])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/) ? null : (obj.title + ' es email');};
PRD.validations['short'] = function(obj) { return obj.value == '' || obj.value.match('\\d*') ? null : (obj.title + ' es short'); };
PRD.validations['integer'] = function(obj) { return obj.value == '' || obj.value.match('\\d*') ? null : (obj.title + ' es integer'); };
PRD.validations['long'] = function(obj) { return obj.value == '' || obj.value.match('\\d*') ? null : (obj.title + ' es long'); };
PRD.validations['float'] = function(obj) { return obj.value == '' || obj.value.match('\\d*(\\.\\d+)?') ? null : (obj.title + ' es float'); };
PRD.validations['double'] = function(obj) { return obj.value == '' || obj.value.match('\\d*(\\.\\d+)?') ? null : (obj.title + ' es double'); };

PRD.prototype.validateElement = function(element) {
    var validation = element.getAttribute('validate');
    var msg = '';
    var hasErrors = false;
    if (validation) {    
        var validations = validation.split(',');
        for (var j=0; j < validations.length; j++) {
            if (PRD.validations[validations[j]]) {
                var errorMessage = PRD.validations[validations[j]](element);
                if (errorMessage) {
                    msg += errorMessage + ' - ';
                    hasErrors = true;                
                }
            }            
        }
        element.style.color = hasErrors ? 'red' : '';
        window.status = msg;
    }    
};

PRD.prototype.validate = function(form) {

    var elements = form.elements;
    var n = elements.length;
    var msg = '';
    var first = null;
    
    for (var i=0; i < n; i++) {
        var validation = elements[i].getAttribute('validate');
        var currentStyle = elements[i].parentNode.currentStyle ? elements[i].parentNode.currentStyle : window.getComputedStyle(elements[i].parentNode,null);
        if (validation && currentStyle.color != 'green' && currentStyle.color != 'rgb(0, 128, 0)') {    
            var validations = validation.split(',');
            var hasErrors = false;
            for (var j=0; j < validations.length; j++) {
                if (PRD.validations[validations[j]]) {
                    var errorMessage = PRD.validations[validations[j]](elements[i]);
                    if (errorMessage) {
                        msg += errorMessage + '\n';
                        first = elements[i];
                        hasErrors = true;
                        elements[i].style.color = 'red';
                    }    
                }            
            }
            elements[i].style.color = hasErrors ? 'red' : '';
        }    
    }
    
    if (msg.length) {
        alert(msg);
        try { first.focus(); } catch (e) {}
        return false;
    }
    
    return true;
    
};

/******************** cruds *****************************/

PRD.prototype.apply = function(me, handler, confirmed, prompted) {

    var container = me.getContainer();
    var xml = container.getElementById('xml');
    me.setDisabled(true);
    prd.hasErrors = '';
    
    
    
    // rich texts
    var xmlOuter = xml.outerNode;
    if (xmlOuter && xmlOuter.triggers && xmlOuter.triggers['__onapply']) {
        for (var i=0; i < xmlOuter.triggers['__onapply'].length; i++) {
            xmlOuter.triggers['__onapply'][i].execute(null, me);
        }
    }

    // validate
    if (prd.hasErrors.length || !this.validate(container.getElementById('form').outerNode)) {
        if (prd.hasErrors.length) {
            alert(prd.hasErrors);
        }
        me.setDisabled(false);
        return false;
    }

    
    // confirmation handling
    this.setConfirmedAndPrompted(xml, confirmed, prompted);
    
    // set timeout
    var t;
    if (prd.timeoutSeconds) {
        var timeout = function() {
            if (t && !confirm('Pasaron ' + prd.timeoutSeconds + ' segundos, verifique la conexion de su proveedor de Internet, seguir esperando?')) {
                //prd.endTransaction(transactionId);
                me.setDisabled(false);
                xml.abort();
            } else if (t) {
                t = setTimeout(timeout, prd.timeoutSeconds*1000);
            }
        };
        t = setTimeout(timeout, prd.timeoutSeconds*1000);
    }
    
    // init transation
    var tx = prd.startConsole('Applying', false, 'green');
    
    // send the post
    xml.post(function(xmlDoc, status) {
    
    	// end console
    	prd.endConsole(tx);    		
   	
        // clear timeout
        if (t) { clearTimeout(t); t = null; }
        
		// check network error
		if (status != 200) {
			me.setDisabled(false);
			prd.startConsole('Network error', true, 'red');
			return false;
		}
    
        // do the work
        if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
            me.setDisabled(false); 
            prd.startConsole('Error', true, 'red');
            if (xmlDoc != null && xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes()) {
                alert(xmlDoc.documentElement.childNodes[0].nodeValue);
            } else {
                alert('Unable to store');
            }
            return false;
        } else if (xmlDoc.documentElement.tagName == 'confirmation') {
            prd.startConsole('Confirm', true, 'yellow');
            if (confirm(xmlDoc.documentElement.childNodes[0].nodeValue)) {
                return prd.apply(me, handler, (confirmed ? (confirmed+',') : '') + xmlDoc.documentElement.getAttribute('code'));
            } else {
                me.setDisabled(false);
                return;
            }
        } else if (xmlDoc.documentElement.tagName == 'prompt') {
            prd.startConsole('Prompt', true, 'yellow');
            var value;
            if (value = prompt(xmlDoc.documentElement.childNodes[0].nodeValue, '')) {
                return prd.apply(me, handler, confirmed, (prompted ? (prompted+',') : '') + xmlDoc.documentElement.getAttribute('code') + '=' + value);
            } else {
                me.setDisabled(false);
                return;
            }
        } 
        
        prd.startConsole('Saved', true, 'green');
        if (container.node && container.node.listingContainer) {
            prd.listingGetXsl(container.node.listingContainer).refresh();
        }
        if (handler) {
            handler(xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes() ? xmlDoc.documentElement.childNodes[0].nodeValue : null);
        }
        try {
            container.close();
        } catch (e) {
            me.setDisabled(false);
        }
        
    });
    
};

PRD.prototype.setConfirmedAndPrompted = function(xml, confirmed, prompted) {
    var url = xml.getUrl();
    if (url.indexOf('?') >= 0) {
        url = url.split('?')[0];
    }
    url += '?';
    if (confirmed) {
        url += 'confirmed=' + confirmed;
    }
    if (prompted) {
        var prompts = prompted.split(',');
        var promptParam = '';
        for (var i=0; i < prompts.length; i++) {
            promptParam += (i > 0 ? ',' : '') + prompts[i].split('=')[0];
            url += '&' + prompts[i];
        }
        url += '&prompted=' + promptParam;
    }
    xml.setUrl(url);
};

var prd = new PRD();

function evaluated(path, row) {
    if (row.outerNode) {
        row = row.outerNode;
    }
        
    var parts = path.split(new RegExp('(\\[|\\])'));
    var newPath = '';
    var k = 0;
    for (var i=0; i < parts.length; i++) {
        if ((i%2)==0) {
            newPath = newPath + parts[i];
        } else {
            // TODO trim
            if (parts[i] == '*') {
                newPath = newPath + '[(\\d+)]';
            } else {
                var expr = parts[i].replace('ROWNUM', rownum(row, k++));
                newPath = newPath + '[' + eval(expr) + ']';
            }
        }
    }

    return newPath;
}

PRD.prototype.startConsole = function(label, timeout, color) {

	var id = new Date().getTime();
	
	var mainDiv = application.getElementById('transactionConsole');

	if (mainDiv == null) {
		return;
	}
	
	var div = document.createElement('div');
	div.id = id;
	div.innerHTML = label;
	div.style.backgroundColor = color;
	div.style.padding = '4px 5px 3px 5px';
	div.style.borderLeft = '1px solid #ffffff'; 
	div.style.borderRight = '1px solid #aca899';
	
	mainDiv.outerNode.appendChild(div);
	mainDiv.outerNode.style.zIndex = application.nextZIndex++;
	
	if (timeout) {
		setTimeout(function() { div.parentNode.removeChild(div); }, 1000);
	}	
	
	return id;
}


PRD.prototype.endConsole = function(id) {
	if (!id) {
		return;
	} 
	var mainDiv = application.getElementById('transactionConsole');
	if (mainDiv == null) {
		return;
	}
	
	mainDiv = mainDiv.outerNode;	
	for (var i=0; i < mainDiv.childNodes.length; i++) {
		if (mainDiv.childNodes[i].id == id) {
			mainDiv.removeChild(mainDiv.childNodes[i]);	
			return;	
		}
	}	
}

function rownum(row, k) {
    var ks = [];
    
    while (row && row.getAttribute) {
        if (row.getAttribute('row') == 'row') {
            ks[ks.length] = row.rowIndex;
        }
        row = row.parentNode;
    }
    return ks[ks.length-k-1];
}

function evaluateBoolean(xpath, obj) {
    var xsl = '<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:xslt2="http://www.htmli.com/1999/XSL/Transform">';
    xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
    xsl += '<xslt:output method="text" omit-xml-declaration="yes" /><xslt:template match="/">';
    xsl += '<xslt:choose><xslt:when test="' + xpath + '">1</xslt:when><xslt:otherwise>0</xslt:otherwise></xslt:choose>';
    xsl += '</xslt:template></xslt:stylesheet>';
    var xslDocument = XmlDocument.create();
    xslDocument.async = false;
    xslDocument.loadXML(xsl);
    var container = application.wrapNode(obj).getContainer();
    var xmlDoc = container.getElementById('xml').getXmlDocument();
    return xmlDoc.transformNode(xslDocument) == '1';
}
 

PRD.prototype.initialTriggers = function(me) {
    var xml = me.getContainer().getElementById('xml'); //application.wrapNode(document.getElementById(prefix + 'xml'));
        
    if (xml.outerNode.triggers && xml.outerNode.triggers['main'] != null) {
        var c = xml.outerNode.triggers['main'];
        for (var i=0; i < c.length; i++) {
            c[i].execute(null, xml);
        }
    }
};

PRD.prototype.trigger = function(fpath, me) {
    setTimeout(function() {
        prd.triggerWrapped(fpath, me);
    }, 1);
};

PRD.prototype.triggerWrapped = function(fpath, me) {
    c = new Date().getTime();
    me.sync();
    var spath = fpath;
    while (spath.indexOf('[') != -1) {
        spath = spath.replace(new RegExp('\\[[^\\]]*\\]'), '');
    }
    var evaluatedPath = evaluated(fpath, me.outerNode);
    var xml = document.getElementById(me.getContainer().getPrefix() + 'xml');
    if (xml.triggers && xml.triggers[spath]) {
        for (var i=0; i < xml.triggers[spath].length; i++) {
            xml.triggers[spath][i].execute(evaluatedPath, me);
        }
    }                                
};

PRD.prototype.registerAbstract = function(prefix, triggers, handler) {
    var xml = document.getElementById(prefix + 'xml');
    if (xml.triggers == null) {
        xml.triggers = new Array();
    }
    var triggerArray = triggers.split(';');
    for (var i=0; i < triggerArray.length; i++) {
        var k = prd.replaceAll(triggerArray[i], new RegExp('\\[[^\\]]*\\]'), '');
        if (xml.triggers[k] == null) {
            xml.triggers[k] = new Array();
        }
        handler(xml.triggers[k], xml.triggers[k].length, triggerArray[i]);
    }    
};

PRD.prototype.registerInitialTrigger = function(prefix, trigger) {
    var xml = document.getElementById(prefix + 'xml');
    
    if (xml.triggers['main'] == null) {
        xml.triggers['main'] = new Array();
    }
    
    xml.triggers['main'][xml.triggers['main'].length] = trigger;    
};

PRD.prototype.registerCalculatedProperty = function(prefix, slaveFpath, slaveId, calculus, triggers, triggerMode) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, trigger, triggerMode);
    });    
    prd.registerInitialTrigger(prefix, new PRD_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, null, triggerMode));
};

PRD.prototype.registerSubsetParams = function(prefix, slaveFpath, slaveId, params, subset, triggers, whenNotInSubset) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_SubsetParams(slaveFpath, slaveId, params, trigger, subset, whenNotInSubset);
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_SubsetParams(slaveFpath, slaveId, params, null, subset, whenNotInSubset));
    var xml = document.getElementById(prefix + 'xml');
    if (!xml.subsetParams) {
        xml.subsetParams = [];
    }
    xml.subsetParams[slaveId] = params;
};

PRD.prototype.registerIf = function(prefix, slaveFpath, slaveId, condition, triggers, func, applyToCanvas, triggerOnApply) {

    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_If(slaveFpath, slaveId, condition, trigger, func, applyToCanvas);
    });
    if (func != prd.checkIf) {
        prd.registerInitialTrigger(prefix, new PRD_Registration_If(slaveFpath, slaveId, condition, null, func, applyToCanvas));
    }
    if (triggerOnApply) {
        prd.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
            array[index] = new PRD_Registration_If(slaveFpath, slaveId, condition, null, func, applyToCanvas);
        });
    }
};

PRD.prototype.registerCondition = function(prefix, slaveFpath, slaveId, params, triggers, func, rpcService) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_Condition(slaveFpath, slaveId, params, trigger, func, rpcService);
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_Condition(slaveFpath, slaveId, params, null, func, rpcService));
    /* async problems, apply() can be called before this, causing unwanted behaviour 
    if (func == prd.checkUnique) {
        prd.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
            array[index] = new PRD_Registration_Condition(slaveFpath, slaveId, params, null, func, rpcService);
        });
    }*/
};

PRD.prototype.registerDynamicValue = function(prefix, slaveFpath, slaveId, params, triggers, rpcService) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_DynamicValue(slaveFpath, slaveId, params, trigger, rpcService);
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_DynamicValue(slaveFpath, slaveId, params, null, rpcService));
};

PRD.prototype.registerDynamicForEach = function(prefix, slaveFpath, slaveId, params, triggers, service, fullXpath) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_DynamicForEach(slaveFpath, slaveId, params, trigger, service, fullXpath);
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_DynamicForEach(slaveFpath, slaveId, params, null, service, fullXpath));
};

PRD.prototype.registerEmbeddedListing = function(prefix, slaveId, entity, params, triggers, subset, listing, name, containerEntity, module, defaultset) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_EmbeddedListing(slaveId, params, trigger, entity, subset, listing, name, containerEntity, module, defaultset);
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_EmbeddedListing(slaveId, params, null, entity, subset, listing, name, containerEntity, module, defaultset));
};

PRD.prototype.registerRichText = function(prefix, id) {
    prd.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
        array[index] = new PRD_Registration_RichText(id, 'save');
    });
    prd.registerInitialTrigger(prefix, new PRD_Registration_RichText(id, 'read'));
};

PRD.prototype.registerCheckIf = function(prefix, id, constraint, triggers, message) {
    prd.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new PRD_Registration_CheckIf(id, constraint, trigger, message);
    });
    prd.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
        array[index] = new PRD_Registration_CheckIf(id, constraint, trigger, message);
    });
};
        
function PRD_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, trigger, triggerMode) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.calculus = calculus;
    this.trigger = trigger;
    this.triggerMode = triggerMode;
};

function PRD_Registration_SubsetParams(slaveFpath, slaveId, params, trigger, subset, whenNotInSubset) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.subset = subset;
    this.whenNotInSubset = whenNotInSubset;
};

function PRD_Registration_If(slaveFpath, slaveId, condition, trigger, func, applyToCanvas) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.condition = condition;
    this.trigger = trigger;
    this.func = func;
    this.applyToCanvas = applyToCanvas;
};

function PRD_Registration_Condition(slaveFpath, slaveId, params, trigger, func, rpcService) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.func = func;
    this.rpcService = rpcService;
};

function PRD_Registration_DynamicValue(slaveFpath, slaveId, params, trigger, rpcService) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.rpcService = rpcService;
};

function PRD_Registration_DynamicForEach(slaveFpath, slaveId, params, trigger, service, fullXpath) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.service = service;
    this.fullXpath = fullXpath;
};

function PRD_Registration_EmbeddedListing(slaveId, params, trigger, entity, subset, listing, name, containerEntity, module, defaultset) {
    this.slaveId = slaveId;
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.entity = entity;
    this.subset = subset;
    this.listing = listing;    
    this.name = name;
    this.containerEntity = containerEntity;
    this.module = module;
    this.defaultset = defaultset;
};

function PRD_Registration_RichText(id, action) {
    this.id = id;
    this.action = action;
};

function PRD_Registration_CheckIf(constraint, trigger, message) {
    this.constraint = constraint;
    this.trigger = trigger;
    this.message = message;
}

PRD.prototype.replaceAll = function(string, pattern, replacement) {
    while (string.match(pattern)) {
        string = string.replace(pattern, replacement);
    }
    return string;
};

PRD.prototype.escapeParam = function(param) {
    if (param == null) {
        return param;
    }
    var parts = param.split('/');
    var ret = '';
    for (var i=0; i < parts.length; i++) {
        ret += (i>0?'|/':'') + parts[i];
    }
    return ret;
};

PRD_Registration_SubsetParams.prototype.execute = function(evaluatedPath, me) {
    try {
        
        var container = me.getContainer();
        var xsl = container.getElementById('window_subset_' + this.slaveId);
        var xmlmultiple = xsl.getPreviousSibling();
        var xml = xmlmultiple.getFirstChild();
        xmlmultiple.getLastChild().setXml(container.getElementById('xml').getXmlDocument().xml);
        var ud = this.slaveId;
        var canvas = prd.getElementsById(container.getPrefix() + 'div_subset_' + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);
            if (child == evaluatedPath) {
                var url = PRD.SERVER_PATH + this.subset;
                for (var j=0; j < this.params.length; j++) {
                    url += '/' + prd.escapeParam(prd.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]));
                }
                var whenNotInSubset = this.whenNotInSubset;
				xml.setUrl(url);
                
                xml.get(function(c) { 
                    xsl.refresh();
                    var disabled = c.firstChild.disabled;
                    var option = c.firstChild.options && c.firstChild.selectedIndex >= 0 ? c.firstChild.options[c.firstChild.selectedIndex] : null;
                    var value = c.firstChild.value;
                    c.innerHTML = xsl.getInnerHTML(); 
                  //  alert(xsl.getInnerHTML());
                    if (c.firstChild) {
	                    c.firstChild.disabled = disabled;
	                    c.firstChild.value = value;
	                    if (option && value != c.firstChild.value && whenNotInSubset != 'donotshow') {
	                        if (whenNotInSubset == 'shownotvalid') {
	                            option.style.color = 'red';
	                        }
	                        c.firstChild.options[c.firstChild.options.length] = option;
	                        option.selected = true;
	                    }
	                }
                    //this.setValue();
                }, canvas[i]);            
            }
        }
    } catch (e) {
        //throw e;
    }
}

PRD.prototype.getSubsetParams = function(me, slaveId) {
    var xml = document.getElementById(me.getContainer().getPrefix() + 'xml');
    if (xml.subsetParams && xml.subsetParams[slaveId]) {
        return xml.subsetParams[slaveId];
    }       
    return '';
};

PRD_Registration_CalculatedProperty.prototype.execute = function(evaluatedPath, me) {
    try {
        var container = me.getContainer();
        var canvas = prd.getElementsById(container.getPrefix() + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);
            if (child == evaluatedPath || evaluatedPath.match(child.replace(/\[/g, '\\[').replace(/\]/g, '\\]'))) {
                if (this.triggerMode != 'onchangenew' || !canvas[i].value || (canvas[i].value == 0 && canvas[i].tagName.toLowerCase() == 'select')) {
                	if (!prd.isNewOrHidden(canvas[i])) {
	                    var value = prd.evaluateXpath(evaluated(this.calculus, canvas[i]), canvas[i]);
    	                canvas[i].value = value;
                    
        	            var myEvent = application.createEvent('HTMLEvents');
						myEvent.initEvent('change');
						application.wrapNode(canvas[i]).dispatchEvent(myEvent);
					}
                }
            }
        }
        
    } catch (e) {
    	throw e;
    }    
}




function debug(t) {
    var d = application.getElementById('debugdiv');    
    d.setValue(d.getValue() + t + '<br>');
}

PRD_Registration_If.prototype.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    var canvas = prd.getElementsById(container.getPrefix() + (this.applyToCanvas ? 'td_': '') + this.slaveId);

    for (var i=0; i < canvas.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);
        if (evaluatedPath == child || evaluatedPath.match(child.replace(/\[/g, '\\[').replace(/\]/g, '\\]'))) {
            var value = evaluateBoolean(evaluated(this.condition, canvas[i]), canvas[i]);
            if (this.applyToCanvas && canvas[i].parentNode.getAttribute('labelposition') == 'top') {
                this.func(canvas[i].parentNode, value);
                this.func(canvas[i].parentNode.previousSibling, value);                
            } else if (this.applyToCanvas && !canvas[i].parentNode.getAttribute('row')) {
                this.func(canvas[i].parentNode, value);
            } else {
                this.func(canvas[i], value);
            }                    
        }
    }
}

PRD.prototype.displayIf = function(obj, bool) {
    obj.style.display = (bool ? '' : 'none');
};

PRD.prototype.displayTabIf = function(obj, bool) {
    var tab = application.wrapNode(obj);
    var i = 0; 
    while (tab.getPreviousSibling()) {
        i++;
        tab = tab.getPreviousSibling();
    }
    if (bool) {
        tab.getParentNode().showChild(i);
    } else {
        tab.getParentNode().hideChild(i);
    }
};


PRD.prototype.visibleIf = function(obj, bool) {
    obj.style.visibility = (bool ? '' : 'hidden');
};

PRD.prototype.readonlyIf = function(obj, bool) {
    obj.readonly = bool;
};

PRD.prototype.disabledIf = function(obj, bool) {
    obj.disabled = bool;
};

PRD.prototype.checkIf = function(obj, bool) {
    if (!bool) {
        prd.hasErrors += 'No cumple';
    }
    obj.style.backgroundColor = bool ? '': 'red';
};

PRD.prototype.checkUnique = function(obj, isUnique) {
    if (!isUnique) {
        alert('No es unique');
        prd.hasErrors += 'No es unique';
    }
    obj.style.backgroundColor = isUnique ? '': 'red';
};



PRD_Registration_Condition.prototype.execute = function(evaluatedPath, me) {

    var container = me.getContainer();
    var canvas = prd.getElementsById(container.getPrefix() + this.slaveId);
    for (var i=0; i < canvas.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);
        if (child == evaluatedPath) {
            var params = new Array();
            var paramsString = '';
            for (var j=0; j < this.params.length; j++) {
                params[params.length] = prd.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]);
                paramsString += ',params[' + j + ']';
            }
            var x = canvas[i];
            var xmlrpcserver = container.getElementById('xmlrpcserver');
            var func = this.func;
            eval('xmlrpcserver.executeAsync(this.rpcService, function(r) { func(x, r); }' + paramsString + ')');        
        }
    }    
}

PRD_Registration_DynamicValue.prototype.execute = function(evaluatedPath, me) {

    try {
        var container = me.getContainer();
        var canvas = prd.getElementsById(container.getPrefix() + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);
            if (child == evaluatedPath || evaluatedPath.match(child.replace(/\[/g, '\\[').replace(/\]/g, '\\]'))) {
                var params = new Array();
                var p = '';
                for (var j=0; j < this.params.length; j++) {
                    params[params.length] = prd.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]);
                    p += ',params[' + j + ']';
                }
                var x = canvas[i];
                var xmlrpcserver = container.getElementById('xmlrpcserver');
                var setDynamicValue = this.setDynamicValue;
                eval('xmlrpcserver.executeAsync(this.rpcService, function(r) { setDynamicValue(canvas[' + i + '], r);} ' + p + ')');
            }
        }
    } catch (e) {
        throw e;
    }
    
}

PRD_Registration_DynamicValue.prototype.setDynamicValue = function(x, r) {
	/* if null value show empty string */
	r = r == null ? '' : r;
    if (x.type == 'checkbox') {
        x.checked = r || r == 'true';
    } else {
        x.value = r; 
    }
    
    // sync and cascade
	var myEvent = application.createEvent('HTMLEvents');
	myEvent.initEvent('change');
	application.wrapNode(x).dispatchEvent(myEvent);
};

PRD_Registration_DynamicForEach.prototype.execute = function(evaluatedPath, me) {

    try {
        var container = me.getContainer();
	    var prefix = container.getPrefix();
        var canvas = prd.getElementsById(prefix + 'div_' + this.slaveId);
	    var xslt = container.getElementById('xsl');
	    
	    var xsl = '<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:xslt2="http://www.htmli.com/1999/XSL/Transform">';
	    xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
	    xsl += '<xslt:output method="html" omit-xml-declaration="yes" /><xslt:template match="/">';
	    xsl += xslt.getXslt().selectSingleNode('//*[@id = "' + prefix + 'div_' + this.slaveId + '"]').xml;
	    xsl += '</xslt:template></xslt:stylesheet>';
	    var xslDocument = XmlDocument.create();
	    xslDocument.async = false;
	    xslDocument.loadXML(xsl);
    
	    var multipleXml = container.getElementById('xmlmultiple').getXmlDocument();
	    
	    // TODO this should be set according to ROWNUM when used in inline environments
	    var fullXpath = this.fullXpath;
	    var xpath = fullXpath.substring(0, fullXpath.lastIndexOf('/'));

	    
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), canvas[i]);

            if (child == evaluatedPath || evaluatedPath.match(child.replace(/\[/g, '\\[').replace(/\]/g, '\\]'))) {
                var params = new Array();
                var p = '';
                for (var j=0; j < this.params.length; j++) {
                    params[params.length] = prd.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]);
                    p += '/' + params[j];
                }
                var x = canvas[i];
                
			   // var oldNode = multipleXml.selectSingleNode('/*/' + xpath + '/' + property);
				var xml = XmlDocument.create();
				xml.onreadystatechange = function() {
					if (xml.readyState == 4) {
						if (xml.parseError.errorCode != 0) {
							alert(xml.parseError.reason);
							return;
						}
						
						// append new lines to xml
						var parentNode = multipleXml.selectSingleNode(xpath);
						var childNodes = multipleXml.selectNodes(fullXpath);
						for (var k=childNodes.length-1; k>=0; k--) {
							childNodes[k].parentNode.removeChild(childNodes[k]);
						}
						var newNodes = xml.documentElement.childNodes;
						var n = newNodes.length;
						for (var k=0; k < n; k++) {
							// TODO importnode for ff3
							parentNode.appendChild(newNodes[0]); // 0 since newNodes length decreases on each cycle
						}
						
						// refresh html
						container.getElementById('xml').setXml(multipleXml.selectSingleNode(xpath).xml);
						x.innerHTML = multipleXml.transformNode(xslDocument);
					
					}
				};
				xml.load(PRD.SERVER_PATH + this.service + p);
            }
        }
    } catch (e) {
        throw e;
    }
    
}


PRD_Registration_EmbeddedListing.prototype.execute = function(evaluatedPath, me) {

    var container = me.getContainer();
    var sources = prd.getElementsById(container.getPrefix() + this.slaveId);
    for (var i=0; i < sources.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(prd.replaceAll(this.trigger, '_', '.'), sources[i]);
        if (child == evaluatedPath) {
            var params = '';
            
            for (var j=0; j < this.params.length; j++) {
                
                if (this.params[j] && this.params[j].length) {
                    params += '/' + prd.escapeParam(prd.evaluateXpath(evaluated(this.params[j], sources[i]), sources[i]));
                }
            }
            var defaultset = this.defaultset;
            prd.openListing(me, this.entity, this.slaveId, this.listing, this.subset + params, true, function(c) {
            	c.getElementById('add').setAttribute('defaultset', defaultset + '/1');
            }, true, '../forms.' + this.module + '/' + this.containerEntity + '_' + this.name + '_embeddedlist.htmli');
        }
    }
}

PRD_Registration_RichText.prototype.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    var riches = prd.getElementsById(container.getPrefix() + this.id);
        
    if (this.action == 'read') {
        var xml = container.getElementById('xml');
        var xmlDoc = xml.getXmlDocument();
        var doNext = function(i) {
        	var r = application.wrapNode(riches[i]);
            r.start();
            setTimeout(function() {
                me = r;
                var expr = eval(r.getAttribute("selectexpr"));
                var node = xmlDoc.selectSingleNode(expr);
                r.setHTMLContents(node.hasChildNodes() ? node.childNodes[0].nodeValue : '');                
            }, 100);
            
            if (i < riches.length-1) {
                doNext(i+1);
            }
        };
        
        if (riches.length > 0) {
            doNext(0);
        }
    } else {
        var xml = container.getElementById('xml');
        var xmlDoc = xml.getXmlDocument();
        for (var j=0; j < riches.length; j++) {
            var r = application.wrapNode(riches[j]);
            var htmlText = r.getHTMLContents();
            var me = r;
            var expr = eval(r.getAttribute("selectexpr"));
            var node = xmlDoc.selectSingleNode(expr);
            var newNode = xmlDoc.createTextNode(htmlText);            
            if (!node.hasChildNodes()) {
                node.appendChild(newNode);
            } else {
                for (var i=node.childNodes.length-1; i >= 0; i--) {
                    node.removeChild(node.childNodes[i]);
                }
                node.appendChild(newNode);
            }
        }        
        xml.setXml(xmlDoc.xml);
    }
        
};

PRD_Registration_CheckIf.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    
    var value = evaluateBoolean(this.condition, me);

};

PRD.prototype.evaluateXpath = function(xpath, obj) {

    var xslCollection = '<xslt:for-each select="' + xpath + '"><xslt:value-of select="." /><xslt:if test="position()!=last()">,</xslt:if></xslt:for-each>';
    var xslSingle = '<xslt:value-of select="' + xpath + '" />';

    var buildXsl = function(m) {
        var xsl = '<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:xslt2="http://www.htmli.com/1999/XSL/Transform">';
        xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
        xsl += '<xslt:output method="text" omit-xml-declaration="yes" /><xslt:template match="/">';
        xsl += m;
        xsl += '</xslt:template></xslt:stylesheet>';
        return xsl;
    }
    
    var xslDocument = XmlDocument.create();
    xslDocument.async = false;
    xslDocument.loadXML(buildXsl(xslCollection));
    var container = application.wrapNode(obj).getContainer();
    var xmlDoc = container.getElementById('xml').getXmlDocument();
    try {
        return xmlDoc.transformNode(xslDocument);
    } catch (e) {
        xslDocument.async = false;
      	xslDocument.loadXML(buildXsl(xslSingle));
    	return xmlDoc.transformNode(xslDocument);
    }
};


PRD.prototype.getElementsById = function(id) {
    if (document.all) {
        var ret = document.all[id];
        return ret == null ? [] : (ret.length == null || ret.length == 0 
            || (ret.tagName && ret.tagName.toLowerCase() == 'select') ? [ret] : ret); 
    } else if(document.evaluate) {
        var ret = new Array();    
        var result = document.evaluate("//*[@id='" + id + "']", document, null, 0, null);
        while (ret[ret.length] = result.iterateNext()) { }
        ret.pop();
        return ret;
    }
};

PRD.prototype.openListing = function(me, entity, canvas, listing, subset, replace, handler, skipWindow, url) {
    var container = me.getContainer();
    if (replace) {
        container.getElementById(canvas).setInnerHTML('');
    }

    // clone source
    var sourcePrototype = application.getElementById('source').cloneNode(true);
    sourcePrototype.setId('listing' + Math.random());
    sourcePrototype.setInnerHTML('');
    
    // append source to canvas
    if (container.getElementById(canvas)) {
        container.getElementById(canvas).appendChild(sourcePrototype);
    } else {
        application.getElementById(canvas).appendChild(sourcePrototype);
    }
    
    // console
    var txOpenListing = prd.startConsole('Opening listing', false, 'green');
    
    // load source
    sourcePrototype.setUrl(url ? url : (entity + (listing && listing.length > 0 ? '_' : '') + listing + (skipWindow ? '_baselist.htmli' : '_list.htmli')));
    sourcePrototype.open(function() {
   		
    	if (!sourcePrototype.isOpened()) {
		   	prd.endConsole(txOpenListing);
	   		prd.startConsole('Network error', true, 'red');
	   		return;
    	}
    	
        var childContainer = sourcePrototype.getChildContainer();
        var xsl = prd.listingGetXsl(childContainer);
        xsl.getStyle().display = '';
        var baseurl = PRD.SERVER_PATH + entity + (subset && subset.length > 0 ? ('/' + subset) : '');
        xsl.setUrl(baseurl + ',page1');
        xsl.setAttribute('baseurl', baseurl);
        if (!skipWindow) {
            var childContainer = sourcePrototype.getChildContainer();
            if (childContainer.node) {
                childContainer.node.canvas = childContainer.getElementById('window');
            } else {
                application.canvas = childContainer.getElementById('window');
            }
        }
       
       xsl.refresh(function(foo, xmlDoc, status) {
    	
    		// end console
        	prd.endConsole(txOpenListing);
        	
        	// check network error
        	if (status != 200) {
        		prd.startConsole('Network error', true, 'green');  
        		return;
        	}
        	
        	// check service error
        	if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        		prd.startConsole('Network error', true, 'red'); 
				if (xmlDoc != null && xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes()) {
					alert(xmlDoc.documentElement.childNodes[0].nodeValue);
				} else {
					alert('Unable to read');
				}
        		return; 
        	}
        	
        	// call handler
        	if (handler) {
                handler(xsl.getContainer());                
            }
            
            // open window
            if (!skipWindow) {
                var win = childContainer.getElementById('window');
                win.open();                
            }
        });
    });
        
    
};

PRD.prototype.loadListing = function(container, entity, subset, openWindow, canvas) {
	// this method is only used from body.onload in *list

    var xsl = container.getElementById('xsl_1_1');
    xsl.setUrl(PRD.SERVER_PATH + entity + (subset ? ('/' + subset + '') : '') + ',page1');
    xsl.getStyle().display = '';

    if (openWindow) {
        canvas = container.getElementById('window');
    }

    if (canvas) {
		if (container.node) {
            container.node.canvas = canvas;
        } else {
            application.canvas = canvas;
        }
    }
    
    // console
    var tx = prd.startConsole('Loading listing', false, 'green');

    xsl.refresh(function() {
    	// TODO if (network or service error) return error
    
    	prd.endConsole(tx);
    	prd.startConsole('Listing ok', true, 'green');
    	
        if (openWindow) {
            var win = container.getElementById('window');
            win.open();
        }
        
    }, true);
}

PRD.prototype.resizeTable = function(xsl) {
	try {
	    var container = xsl.getContainer();
	    var canvas = (container.node && container.node.canvas) ? container.node.canvas : (application.canvas ? application.canvas : null);
	    if (canvas) {
	        var table = prd.listingGetTable(container);
	        xsl.getStyle().display = 'none';
	        var canvasHeight = canvas.getHeight() - 30;
	        xsl.getStyle().display = '';
	        var diff = canvasHeight - container.getElementById('maindiv').getHeight();
	        table.getStyle().height = (table.getHeight() + diff)+'px';
	        table.getStyle().overflowY = 'scroll';
	    }
	} catch (e) {
	
	}
};


PRD.prototype.onResizeListWindow = function(me) {
    /* at the moment of calling this function the window is not visible, just the 
        dotted box shown at resizing time, so timeout is needed */
    setTimeout(function() {
    prd.resizeTable(prd.listingGetXsl(me.getContainer())); }, 10);
};



PRD.prototype.openRelatedListing = function(me, entity, listing, subset, subsetparams) {
    var id = '';
    if (subsetparams) {
        var params = subsetparams ? subsetparams.split(';') : [];
        for (var j=0; j < params.length; j++) {
            id += (j > 0 ? '/' : '') + prd.evaluateXpath(params[j], me);
        }
    }

    return prd.openListing(me, entity, 'formcanvas', listing, subset + (subset && id ? '/' : '') + id);
};

PRD.prototype.openRelatedForm = function(me, entity, defaultset, defaultsetparams) {
    var id = '';
    if (defaultset) {
        var params = defaultsetparams ? defaultsetparams.split(';') : [];
        for (var j=0; j < params.length; j++) {
            id += (j > 0 ? '/' : '') + prd.evaluateXpath(params[j], me);
        }
    }

    return prd.openForm(me, entity, 'formcanvas', id, defaultset);    
};


PRD.prototype.openForm = function(me, entity, canvas, id, defaultset, module, skipWindow) {
    var container = me.getContainer();
    var sourcePrototype = application.getElementById('source').cloneNode(true);
    application.getElementById(canvas).appendChild(sourcePrototype);
    sourcePrototype.setUrl((module ? ('../forms.' + module + '/') : '') + entity + (skipWindow ? '_baseform.htmli' : '_form.htmli'));
    
    // start console
    var txOpenForm = prd.startConsole('Opening form', false, 'green');
    
    sourcePrototype.open(function() {
    	// end console
    	prd.endConsole(txOpenForm);
    
    	if (!sourcePrototype.isOpened()) {
		    var tx = prd.startConsole('Network error', true, 'red');    		
		    return;
    	}
    
        var childContainer = sourcePrototype.getChildContainer();
        prd.loadForm(childContainer, entity, id, defaultset, !skipWindow);
    });
    sourcePrototype.getChildContainer().node.listingContainer = container;
    
};

PRD.prototype.loadForm = function(container, entity, id, defaultset, openWindow, handler, confirmed, prompted) {
    var children = container.getElementById('xmlmultiple').getChildNodes();
    for (var i=0; i < children.getLength(); i++) {
        if (children.item(i).getAttribute('baseurl')) {
            children.item(i).setUrl(PRD.SERVER_PATH + children.item(i).getAttribute('baseurl'));
        }
    }
    
    var xsl = container.getElementById('xsl');
    var xml = container.getElementById('xml');
    xml.setUrl(PRD.SERVER_PATH + entity + '/' + (defaultset ? (defaultset + '/') : '') + id);
	
	// confirmation handling
    this.setConfirmedAndPrompted(xml, confirmed, prompted);
    
    // console
	var tx = prd.startConsole('Loading', false, 'green');
	
    xml.setUrl(xml.getUrl() + '&' + new Date().getTime());    
    xsl.refresh(function(foo, xmlDoc, status) {
    	// end console
    	prd.endConsole(tx);

    	if (status != 200) {
    		alert('network error');
    		prd.startConsole('Network error', true, 'red');
    		return;
    	}
    	
    	var xmlDoc = xml.getXmlDocument();  
    	if (!PRD.ignoreErrors) {  
			if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
	            prd.startConsole('Error', true, 'red');
	            if (xmlDoc != null && xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes()) {
	                alert(xmlDoc.documentElement.childNodes[0].nodeValue);
	            } else {
	                alert('Unable to read');
	            }
	            return false;
	        } else if (xmlDoc.documentElement.tagName == 'confirmation') {
	            prd.startConsole('Confirm', true, 'yellow');
	            if (confirm(xmlDoc.documentElement.childNodes[0].nodeValue)) {
	                return prd.loadForm(container, entity, id, defaultset, openWindow, handler, (confirmed ? (confirmed+',') : '') + xmlDoc.documentElement.getAttribute('code'));
	            } else {
	                return;
	            }
	        } else if (xmlDoc.documentElement.tagName == 'prompt') {
	            prd.startConsole('Prompt', true, 'yellow');
	            var value;
	            if (value = prompt(xmlDoc.documentElement.childNodes[0].nodeValue, '')) {
	                return prd.loadForm(container, entity, id, defaultset, openWindow, handler, confirmed, (prompted ? (prompted+',') : '') + xmlDoc.documentElement.getAttribute('code') + '=' + value);
	            } else {
	                return;
	            }
	        } 
	    	prd.startConsole('Opened ok', true, 'green');
		}   
        if (openWindow) {
            var win = container.getElementById('window');
            win.open();        
            /* Resize window with new contents size*/
            var height = win.getHeight();
            var width = win.getWidth();    	
            win.resizeTo(width, height, true);
        }
        if (handler) {
            handler();
        }
    }, true);
};

PRD.prototype.getRowFor = function(me) {
    var row = me.outerNode;
    while (row && row.getAttribute) {
        if (row.getAttribute('row') == 'row') {
            return row;            
        }
        row = row.parentNode;
    }    
};

PRD.prototype.suggestKeyDown = function(me, entity, property, ev) {
    /*if (ev.getKeyCode() == 13) {
        ev.stopPropagation();
        ev.preventDefault();
    }  else if (ev.getKeyCode() == 9) {
        var container = me.getContainer();
        var xsl = container.getElementById('suggests');
        var input = xsl.outerNode.input;
        if (input) {
            application.wrapNode(input).sync();
        }
    }*/            
};

PRD.prototype.suggestDblClick = function(me, entity, property) {
    this.suggest(me, entity, property);
};

PRD.prototype.suggestBlur = function(me, entity, property) {
    var container = me.getContainer();
    var xsl = container.getElementById('suggests');
    setTimeout(function() {
        xsl.getStyle().display = 'none';
    }, 250);
    xsl.outerNode.suggestSelectedIndex == null
};

PRD.prototype.suggestKeyUp = function(me, entity, property, ev) {

    var container = me.getContainer();
    var xsl = container.getElementById('suggests');        
    
    if (ev.getKeyCode() == 9 || ev.getKeyCode() == 27 || ev.getKeyCode() == 13 || (me.getValue().length < 1 && ev.getKeyCode() != 40 && ev.getKeyCode() != 38)) {
        xsl.outerNode.suggestSelectedIndex == null
        xsl.getStyle().display = 'none';
        return;
    }

    
    if (ev.getKeyCode() == 40 && xsl.getStyle().display != 'none') {
    
        if (xsl.outerNode.suggestSelectedIndex == null) {
            xsl.outerNode.suggestSelectedIndex = -1;
        }
        
        if (xsl.outerNode.suggestSelectedIndex >= xsl.getChildNodes().getLength()-1) {
            return;
        }
        if (xsl.outerNode.suggestSelectedIndex >= 0) {
            var oldItem = xsl.getChildNodes().item(xsl.outerNode.suggestSelectedIndex);
            oldItem.getStyle().backgroundColor = '';
            oldItem.getStyle().color = '';
        }
        
        xsl.outerNode.suggestSelectedIndex++;
        var item =    xsl.getChildNodes().item(xsl.outerNode.suggestSelectedIndex);
        item.getStyle().backgroundColor = '#000099';
        item.getStyle().color = '#ffffff';        
        me.setValue(item.outerNode.title);
        if (me.dispatchChangeEvent) {
            me.dispatchChangeEvent();
        }
                
    } else if (ev.getKeyCode() == 38 && xsl.getStyle().display != 'none') {
        if (xsl.outerNode.suggestSelectedIndex == null) {
            xsl.outerNode.suggestSelectedIndex = -1;
        }
        
        if (xsl.outerNode.suggestSelectedIndex <= 0) {
            return;
        }
        
        if (xsl.outerNode.suggestSelectedIndex >= 0) {
            var oldItem = xsl.getChildNodes().item(xsl.outerNode.suggestSelectedIndex);
            oldItem.getStyle().backgroundColor = '';
            oldItem.getStyle().color = '';
        }
        
        xsl.outerNode.suggestSelectedIndex--;
        var item =    xsl.getChildNodes().item(xsl.outerNode.suggestSelectedIndex);
        item.getStyle().backgroundColor = '#000099';
        item.getStyle().color = '#ffffff';        
        me.setValue(item.outerNode.title);
        if (me.dispatchChangeEvent) {
            me.dispatchChangeEvent();
        }
        //me.sync();
        
    } else if (ev.getKeyCode() != 16) {
        if (me.getValue().length || ev.getKeyCode() == 40) {
            this.suggest(me, entity, property);
        }
        
    }
        
};

PRD.prototype.suggest = function(me, entity, property) {
    var container = me.getContainer();
    var xsl = container.getElementById('suggests');
    xsl.outerNode.suggestSelectedIndex = null;
    xsl.setUrl(PRD.SERVER_PATH + entity + '/suggest' + property + '/' + me.getValue());
    xsl.outerNode.input = me.outerNode;
    xsl.refresh(function() {
        var style = xsl.getStyle();
        style.top = (me.getY() - xsl.getContainingBlock().getY() + me.getHeight()-2) + "px";
        style.left = (me.getRelativeX()-4) + "px";    
        style.display = xsl.hasChildNodes() ? '' : 'none';        
    });
};

PRD.prototype.multilineRemove = function(me, fpath) {
    var container = me.getContainer();
    var row = prd.getRowFor(me);
    var xpath = evaluated(fpath, row);
    var xml = container.getElementById('xml');
    xml.remove(xpath);
    row.parentNode.removeChild(row);
    return;    
};

PRD.prototype.multilineInsert = function(me, xpath, property) {
    return prd.multilineAdd(me, xpath, property, prd.getRowFor(me).rowIndex+1);
};

PRD.prototype.multilineUp = function(me, xpath) {
    var row = prd.getRowFor(me);    
    if (row.rowIndex > 1) {
        var container = me.getContainer();    
        var xml = container.getElementById('xml');
        var xmlDoc = xml.getXmlDocument();    
        var node = xmlDoc.selectSingleNode(evaluated(xpath, row));
        node.parentNode.insertBefore(node, node.previousSibling);
        xml.setXml(xmlDoc.xml);    
    
        row.parentNode.insertBefore(row, row.previousSibling);
    }
    
};

PRD.prototype.multilineDown = function(me, xpath) {
    var row = prd.getRowFor(me);    
    if (row.rowIndex < row.parentNode.childNodes.length-3) {
        var container = me.getContainer();    
        var xml = container.getElementById('xml');
        var xmlDoc = xml.getXmlDocument();    
        var node = xmlDoc.selectSingleNode(evaluated(xpath, row));
        node.parentNode.insertBefore(node, node.nextSibling.nextSibling);
        xml.setXml(xmlDoc.xml);    
        row.parentNode.insertBefore(row, row.nextSibling.nextSibling);
    }    
};

PRD.prototype.multilineAdd = function(me, fpath, property, rowNum) {
    var tr = prd.getRowFor(me);
    
    var tbody = tr.parentNode;    
    
    var container = me.getContainer();    
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();
    if (rowNum) {
        var node = xmlDoc.selectSingleNode(evaluated(fpath + '/' + property + '[ROWNUM]', tr));
        if (node.nextSibling) {
            node.parentNode.insertBefore(xmlDoc.createElement(property), node.nextSibling);
        } else {
            node.parentNode.appendChild(xmlDoc.createElement(property));
        }
    } else {
        var node = xmlDoc.selectSingleNode(evaluated(fpath, tbody));
        node.appendChild(xmlDoc.createElement(property));
    }
    xml.setXml(xmlDoc.xml);    
    var newTr = tbody.lastChild.previousSibling.cloneNode(true);               
    newTr.style.color = '';                         
    newTr.style.display = '';  
    tr.parentNode.insertBefore(newTr, rowNum ? tbody.childNodes[rowNum] : tbody.lastChild.previousSibling); 
    //for (var i=0; i < newTr.childNodes.length; i++) {
    //    newTr.childNodes[i].style.display = '';
    //}	display only first child so as to keep hidden remove button in last row
    newTr.childNodes[0].style.display = '';
    try {
        newTr.firstChild.firstChild.focus();    
    } catch (e) {
    
    }

};

PRD.prototype.multilineInsertEntity = function(me, xpath, entity) {
    return prd.multilineAddEntity(me, xpath.substring(0, xpath.lastIndexOf('/')), xpath.substring(xpath.lastIndexOf('/')+1, xpath.lastIndexOf('[')), entity, prd.getRowFor(me).rowIndex+1);
};

PRD.prototype.multilineAddEntity = function(me, fpath, property, entity, rowNum, async) {
    var tr = prd.getRowFor(me);
    
    var tbody = tr.parentNode;    
    var container = me.getContainer();    
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();
    
    // console
    var tx = prd.startConsole('Adding', false, 'green');
    
    var httpRequest = HttpRequest.create();
    httpRequest.open("GET", PRD.SERVER_PATH + entity + '/0?' + new Date().getTime(), false);
    httpRequest.onreadystatechange = function() {                    
        if (httpRequest.readyState == 4) {
        
        	// end console
        	prd.endConsole(tx);
        	
        	// TODO if (network or service error) return error
        
            var newNode = xmlDoc.createElement(property);
            var childDoc = httpRequest.responseXML;
            var children = childDoc.documentElement.childNodes;
            for (var i=0; i < children.length; i++) {
                var n = children[i].cloneNode(true);
                /*if (n.tagName != path.substring(1)) {*/
                    newNode.appendChild(n);
                /*}*/
            }
            newNode.setAttribute('id', 0);
            if (rowNum) {
                var n = xmlDoc.selectSingleNode(evaluated(fpath, tbody) + '/' + property + '[' + rowNum + ']');
                n.parentNode.insertBefore(newNode, n);
            } else {
                xmlDoc.selectSingleNode(evaluated(fpath, tbody)).appendChild(newNode);
            }
            xml.setXml(xmlDoc.xml);
            
            var newTr = tbody.lastChild.previousSibling.cloneNode(true);
            newTr.style.color = '';                       
            newTr.style.display = '';
            newTr.onkeydown = function() {};            
            tr.parentNode.insertBefore(newTr, rowNum ? tbody.childNodes[rowNum] : tbody.lastChild.previousSibling);
            //prd.multilineCalculateIndexes(tbody);
        }
    };
    httpRequest.send("");
            
};

PRD.prototype.multilineCalculateIndexes = function(tbody) {
    for (var i=0; i < tbody.childNodes.length; i++) {
        tbody.childNodes[i].firstChild.firstChild.value = i;
    }
};

PRD.prototype.checkIfIsNew = function(me) {

    var node = me.outerNode;

    while (node && node.parentNode && node.parentNode.getAttribute) {
        node = node.parentNode;
        if (node.getAttribute("row")) {
            if (node.parentNode.getAttribute('extendable') == 'extendable') {
                var current = node.rowIndex;
                var total = node.parentNode.childNodes.length;
                if (current == (total-3)) {
                    
                    if (node.getAttribute('entity')) {
                        // TODO this is async!
                        prd.multilineAddEntity(me, node.getAttribute('selectexpr').substring(0, 
                            node.getAttribute('selectexpr').lastIndexOf('/')), node.getAttribute('property'), node.getAttribute('entity'), null, true);
                    } else {
                        prd.multilineAdd(me, node.getAttribute('selectexpr'), node.getAttribute('property'));
                    }    
                    for (var i=0; i < node.childNodes.length; i++) {
                        node.childNodes[i].style.display = '';
                    }
                    
                }
            }
            break;
        }
    }

};

PRD.prototype.isNewOrHidden = function(me) {

    var node = me;

    while (node && node.parentNode && node.parentNode.getAttribute) {
        node = node.parentNode;
        if (node.getAttribute("row")) {
            if (node.parentNode.getAttribute('extendable') == 'extendable') {
                var current = node.rowIndex;
                var total = node.parentNode.childNodes.length;
                return current == (total-3) || current == (total-2);
            }
            break;
        }
    }
    return false;

};


PRD.prototype.multilineChangedNew = function(me, fpath, property, entity, rowNum) {
//    me.outerNode.onkeydown = function() {};
//    prd.multilineAddEntity(me, fpath, property, entity, rowNum);
// alert(1);
};

 
PRD.prototype.multilineDetailAdd = function(me, selectexpr, name, id, entity) {
    var tbody = me.outerNode.previousSibling.previousSibling.lastChild;
    
    // TODO make this method work as with suggest one embedded entity
    
    var newTR = tbody.insertRow(tbody.childNodes.length-1);
    newTR.setAttribute('row', 'row');
    var newCell = newTR.insertCell();
    var div = document.createElement('div');
    div.id = 'row_' + id;
    newCell.appendChild(div);
    
/*    tbody.lastChild.cloneNode(true);
    tbody.appendChild(newTR);
    tbody.childNodes[tbody.childNodes.length-2].style.display = '';
    */
    
    prd.suggestEmbeddedEntity(me, application.wrapNode(div), selectexpr, entity, name, null, true);

};

PRD.prototype.showHideEmbeddedEntity = function(me, xpath, entity, property, value, handler) {
    var container = me.getContainer();
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();
    var checked = typeof(value)!='undefined' ? value : me.getChecked();
    var div = me.getParentNode().getNextSibling();
    
    var xpath = evaluated(xpath, me);
    var node = xmlDoc.selectSingleNode(xpath + '/' + property);
    if (node) {
        node.setAttribute('id', checked ? 1 : -1);
        xml.setXml(xmlDoc.xml);
        if(handler) {
            handler();
        }
    } else if (checked) {
        prd.suggestEmbeddedEntity(me, div, xpath, entity, property, handler);
    }
    var style = div.getStyle();
    style.visibility = checked ? 'visible' : 'hidden';
    style.color = checked ? '' : 'green';
}

PRD.prototype.suggestEmbeddedEntity = function(me, div, xpath, entity, property, handler, isMultiLine) {
    
    var container = me.getContainer();
    var prefix = container.getPrefix();
    
    var xslt = container.getElementById('xsl');
    
    var lcFirstEntity = entity.substring(0,1).toLowerCase() + entity.substring(1);
        
    var xsl = '<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:xslt2="http://www.htmli.com/1999/XSL/Transform">';
    xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
    xsl += '<xslt:output method="html" omit-xml-declaration="yes" /><xslt:template match="/">';
    xsl += xslt.getXslt().selectSingleNode('//*[@id = "' + prefix + div.getId() + '"]').xml;
    xsl += '</xslt:template></xslt:stylesheet>';
    var xslDocument = XmlDocument.create();
    xslDocument.async = false;
    xslDocument.loadXML(xsl);
        

    var multipleXml = container.getElementById('xmlmultiple').getXmlDocument();
    var oldNode = multipleXml.selectSingleNode('/*/' + xpath + '/' + property);
        
    var xml = XmlDocument.create();
    
    // console
    var tx = prd.startConsole('Embedding', false, 'green');
    
    xml.onreadystatechange = function() {
        if (xml.readyState == 4) {
        	// end console
        	prd.endConsole(tx);
        
        	// TODO if (network or service error) return error
        	
            if (xml.parseError.errorCode != 0) {
                alert(xml.parseError.reason);
                return;
            }
            
            if (!oldNode || isMultiLine) {
                oldNode = multipleXml.createElement(property);
                var parentNode = multipleXml.selectSingleNode('/*' + xpath);
                parentNode.appendChild(oldNode);
            }
            
            var n = oldNode.childNodes.length;
            for (var i=0; i < n; i++) {
                oldNode.removeChild(oldNode.childNodes[0]);
            }
            
            var children = xml.documentElement.childNodes;
            for (var i=0; i < children.length; i++) {
                oldNode.appendChild(children[i].cloneNode(true));
            }
        
            oldNode.setAttribute('id', isMultiLine ? 0 : 1);
            container.getElementById('xml').setXml(multipleXml.selectSingleNode('/root' + xpath).xml);
            div.setInnerHTML(multipleXml.transformNode(xslDocument));
            if (handler) {
                handler();
            }
        }
    };        
    // TODO add subset or defaultset
    xml.load(PRD.SERVER_PATH + entity + '/0');
}

PRD.prototype.textareaCollectionSync = function(me, expr, name) {
    var values = me.getValue().split('\n');
    
    var container = me.getContainer();
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();
    var selectexpr = evaluated(expr + '/' + name, me);
    
    var nodes = xmlDoc.selectNodes(selectexpr);
    for (var i=nodes.length-1; i >= 0; i--) {
        nodes[i].parentNode.removeChild(nodes[i]);
    }
    
    var parentNode = xmlDoc.selectSingleNode(evaluated(expr, me));
    for (var i=0; i < values.length; i++) {
        if (values[i] && values[i].replace(/^\s+|\s+$/g,'').length) {
            var newNode = xmlDoc.createElement(name);
            newNode.appendChild(xmlDoc.createTextNode(values[i].replace(/^\s+|\s+$/g,'')));
            parentNode.appendChild(newNode);
        }
    }
    
    xml.setXml(xmlDoc.xml);
    
};

PRD.prototype.collectionKeyDown = function(me, ev, xpath, property) {
    var select = me.outerNode;
    var container = me.getContainer();    
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();    
//    var row = prd.getRowFor(me);    

    if (ev.getKeyCode() == 38 && ev.getCtrlKey() && select.selectedIndex > 0) {
        var selectedIndex = select.selectedIndex;

        var aux = select.options[selectedIndex-1];
        select.options[selectedIndex-1] = new Option(select.options[selectedIndex].text, select.options[selectedIndex].value);
        select.options[selectedIndex] = aux;
        select.options[selectedIndex].selected = true;

        var node1 = xmlDoc.selectSingleNode(evaluated(xpath, select) + '/' + property + '[' + (selectedIndex) + ']');    
        var node2 = xmlDoc.selectSingleNode(evaluated(xpath, select) + '/' + property + '[' + (selectedIndex+1) + ']');    
        node1.parentNode.insertBefore(node2, node1);
    
    } else if (ev.getKeyCode() == 40 && ev.getCtrlKey() && select.selectedIndex < (select.options.length-1)) {
        var aux = select.options[select.selectedIndex+1];
        var s = select.selectedIndex;
        select.options[select.selectedIndex+1] = new Option(select.options[select.selectedIndex].text, select.options[select.selectedIndex].value);
        select.options[select.selectedIndex] = aux;
        select.options[s].selected = true;
        
        var node1 = xmlDoc.selectSingleNode(evaluated(xpath, select) + '/' + property + '[' + (select.selectedIndex+1) + ']');    
        var node2 = xmlDoc.selectSingleNode(evaluated(xpath, select) + '/' + property + '[' + (select.selectedIndex+2) + ']');    
        node1.parentNode.insertBefore(node2, node1);
    
    } else {
        return;
    }
    
    xml.setXml(xmlDoc.xml);    
};

PRD.prototype.collectionRemoveEntity = function(me, xpath, property) {
    var select = me.outerNode;
    if (select.selectedIndex >= 0) {

        // sync
        var container = me.getContainer();
        var xml = container.getElementById('xml');
        var xmlDoc = xml.getXmlDocument();
    
        var node = xmlDoc.selectSingleNode(evaluated(xpath, me) + '/' + property + '[' + (select.selectedIndex+1) + ']');
        node.parentNode.removeChild(node);
        xml.setXml(xmlDoc.xml);
        
        // display
        select.remove(select.selectedIndex);
    }
};



PRD.prototype.collectionAddEntity = function(me, id, entity, subset, subsetparams, minrows, maxrows, displayCanvas, unique, firstPage) {
    var select = me.getParentNode().getParentNode().getFirstChild();

    if (maxrows && select.outerNode.options.length >= maxrows) {
        alert('Max rows: ' + maxrows);
        return false;
    }

    var container = me.getContainer();
    var selectxsl = container.getElementById('window_select_xsl' + id);
    if (subset && subset != '') {
        var url = PRD.SERVER_PATH + entity + '/' + subset;
        if (subsetparams && subsetparams.length) {
	        var params = subsetparams.split(';');
	        for (var j=0; j < params.length; j++) {
	            url += '/' + prd.escapeParam(prd.evaluateXpath(evaluated(params[j], me), me));
	        }
	    }
        selectxsl.setUrl(url + (firstPage ? ',page1' : ''));        
    } else {
        selectxsl.setUrl(PRD.SERVER_PATH + entity + (firstPage ? ',page1' : ''));
    }
    
    selectxsl.setAttribute('baseurl', selectxsl.getUrl());
    
    // console
    var tx = prd.startConsole('Add', false, 'green');
    
    selectxsl.refresh(function() {
    	// console
    	prd.endConsole(tx);
    	
    	// TODO if (network or service error) return error
    
        var windowSelect = selectxsl.getLastChild().outerNode;
        var currentSelect = select.outerNode;
        
        if (unique) {
            for (var i=windowSelect.options.length-1; i >= 0; i--) {
                for (var j=0, n=currentSelect.options.length; j < n; j++) {
                    if (windowSelect.options[i].value == currentSelect.options[j].value) {
                        windowSelect.remove(i);
                        break;
                    }
                }
            }    
        }        
    });
    
    selectxsl.getPreviousSibling().getStyle().display = firstPage ? '' : 'none';
    
    var win = selectxsl.getParentNode();
    win.open();
    win.center();
    
    
    selectxsl.outerNode.slaveSelect = select;
    selectxsl.outerNode.displayCanvas = displayCanvas;
    selectxsl.outerNode.unique = unique;
};

PRD.prototype.collectionSelectFilter = function(input, value, comboproperty) {
    var xsl = input.getNextSibling();
    xsl.setUrl(xsl.getAttribute('baseurl') + (value ? ('!' + comboproperty + '=' + value) : ''));
    xsl.refresh(
    	// TODO if (network or service error) return error
    );
};

PRD.prototype.collectionSelectWindowDblClick = function(me) {
    if (me.getSelectedIndex() == -1) {
        return;
    }
    
    var select = me.getParentNode().outerNode.slaveSelect.outerNode;
    var maxrows = select.getAttribute('maxrows');
    
    if (maxrows && select.options.length >= parseInt(maxrows)) {
        alert('Max rows: ' + maxrows);
        return false;
    }
    
    var container = me.getContainer();
    
    var text = me.outerNode.options[me.outerNode.selectedIndex].text;
    var value = me.outerNode.options[me.outerNode.selectedIndex].value;
    
    select.options[select.options.length] = new Option(text, value);
    
    if (me.getParentNode().outerNode.unique) {
        me.remove(me.getSelectedIndex());
    }
    
    var node = select.getAttribute('property');
    var selectexpr = evaluated(select.getAttribute('selectexpr'), me.getParentNode().outerNode.slaveSelect);
                        
    var xmlDoc = XmlDocument.create();
    xmlDoc.loadXML('<' + node + ' id=\'' + value + '\' />');

    var target = container.getElementById('xml');
    var targetDoc = target.getXmlDocument();
    targetDoc.selectSingleNode(selectexpr).appendChild(xmlDoc.documentElement);
    target.setXml(targetDoc.xml);
    
    var canvas = me.getParentNode().outerNode.displayCanvas;
    if (canvas) {
        var txt = '';
        for (var i=0; i < select.options.length; i++) {
            txt += (i == 0 ? '' : ', ') + select.options[i].text;
        }
        canvas.innerHTML = txt;
        canvas.title = txt;
    }
};

PRD.prototype.comboKeyDown = function(me, entity, ev) {
    if (ev.getKeyCode() == 13) {
        ev.stopPropagation();
        ev.preventDefault();
    } else if (ev.getKeyCode() == 9) {
        var container = me.getContainer();
        var xsl = container.getElementById('window_combo_xsl' + me.getId());
        xsl.getStyle().display = 'none';
        if (me.getNextSibling().getValue() == -1) {
            me.getStyle().color = 'red';
        }
        return;
    }
};

PRD.prototype.comboKeyUp = function(me, entity, ev, subset, subsetparams, comboproperty) {
    var container = me.getContainer();
    var xsl = container.getElementById('window_combo_xsl' + me.getId());        
    
    me.getStyle().color = '';
    
    if (ev.getKeyCode() == 9 || ev.getKeyCode() == 27 || ev.getKeyCode() == 13 || 
            (me.getValue().length < 1 && ev.getKeyCode() != 40 && ev.getKeyCode() != 38)) {
        //return simple.confirmParentChange(me, name);
        xsl.getStyle().display = 'none';
        return;
    }

    if (ev.getKeyCode() == 40 && xsl.getStyle().display != 'none') {
        var tbody = xsl.getLastChild().getFirstChild().getFirstChild().outerNode;
        this.comboMove(xsl, tbody, 1);
        prd.comboSetValue(me, tbody.childNodes[xsl.outerNode.comboSelectedIndex].title, 
                tbody.childNodes[xsl.outerNode.comboSelectedIndex].getAttribute('rowid'));        
        
    } else if (ev.getKeyCode() == 38 && xsl.getStyle().display != 'none') {
        var tbody = xsl.getLastChild().getFirstChild().getFirstChild().outerNode;    
        this.comboMove(xsl, tbody, -1);
        
        prd.comboSetValue(me, tbody.childNodes[xsl.outerNode.comboSelectedIndex].title, 
                tbody.childNodes[xsl.outerNode.comboSelectedIndex].getAttribute('rowid'));    
        
        
    } else if (ev.getKeyCode() != 16) {
        prd.comboShow(me, xsl, entity, ev, subset, subsetparams, comboproperty, true);
    }
};

PRD.prototype.comboMove = function(xsl, tbody, diff) {
    if (xsl.outerNode.comboSelectedIndex == null) {
        xsl.outerNode.comboSelectedIndex = -1;
    }

    if ((diff > 0 && xsl.outerNode.comboSelectedIndex >= tbody.childNodes.length-1) ||
        diff < 0 && xsl.outerNode.comboSelectedIndex <= 0) {
        return;
    }
    
    if (xsl.outerNode.comboSelectedIndex >= 0) {
        var style = tbody.childNodes[xsl.outerNode.comboSelectedIndex].style;
        style.backgroundColor = '';
        style.color = '';
    }
    
    xsl.outerNode.comboSelectedIndex+=diff;
    var style = tbody.childNodes[xsl.outerNode.comboSelectedIndex].style;
    style.backgroundColor = '#000099';
    style.color = '#ffffff';
}

PRD.prototype.comboSetValue = function(keyInput, key, id) {
    if (key != null) {
        keyInput.setValue(key);
    }
    var input = keyInput.getNextSibling();
    input.setValue(id);

    var newEvent = application.createEvent('UIEvents');
    newEvent.initUIEvent('change');
    input.dispatchEvent(newEvent);
    
    keyInput.outerNode.style.backgroundColor = '';
    keyInput.outerNode.style.color = '';    
};

PRD.prototype.suggestClicked = function(obj, value) {
    var input = application.wrapNode(obj);
    
    input.setValue(value);
    
    var newEvent = application.createEvent('UIEvents');
    newEvent.initUIEvent('change');
    input.dispatchEvent(newEvent);

}

PRD.prototype.comboShow = function(me, xsl, entity, ev, subset, subsetparams, comboproperty, setFirst) {
    var url;
    if (subset) {
        url = PRD.SERVER_PATH + entity + '/' + subset;
        var params = subsetparams.split(';');
        for (var j=0; j < params.length; j++) {
            url += '/' + prd.evaluateXpath(evaluated(params[j], me), me);
        }
        url += ',page1';
        url += (me.getValue()? ('!' + comboproperty + '=' + me.getValue()) : '');
    } else {
        url = PRD.SERVER_PATH + entity + ',page1' + (me.getValue()? ('!' + comboproperty + '=' + me.getValue()) : '');
    }
    xsl.setUrl(url);
    xsl.outerNode.comboSelectedIndex = -1;
    xsl.outerNode.comboSelected = me;
    xsl.refresh(function() {
    
    	// TODO if (network or service error) return error
    	
        xsl.getStyle().top = (me.getY() - xsl.getContainingBlock().getY() + me.getHeight()-2) + "px";
        xsl.getStyle().left = (me.getRelativeX()-4) + "px";    
        if (xsl.getLastChild().getFirstChild().getFirstChild().hasChildNodes()) {
            xsl.getStyle().display = '';
            if (setFirst && me.getValue().toLowerCase() == xsl.getLastChild().getFirstChild().getFirstChild().getFirstChild().getTitle().toLowerCase()) {
                prd.comboSetValue(me, xsl.getLastChild().getFirstChild().getFirstChild().getFirstChild().getTitle(), 
                    xsl.getLastChild().getFirstChild().getFirstChild().getFirstChild().getAttribute('rowid'));
            }
        } else {
            xsl.getStyle().display = 'none';                
        }
    });    
    prd.comboSetValue(me, null, -1);    
}
    
PRD.prototype.comboDblClick = function(me, entity, ev, subset, subsetparams, comboproperty) {
    var container = me.getContainer();
    var xsl = container.getElementById('window_combo_xsl' + me.getId());        
    prd.comboShow(me, xsl, entity, ev, subset, subsetparams, comboproperty, false);    
};

PRD.prototype.comboClicked = function(me, id, key, rowid) {
    var container = me.getContainer();
    var xsl = container.getElementById('window_combo_xsl' + id);        
    xsl.getStyle().display = 'none';    
    prd.comboSetValue(xsl.outerNode.comboSelected, key, rowid);    
};

PRD.prototype.checkboxClicked = function(me, selectexpr, name, value, isEntity, refreshCanvas) {
    selectexpr = evaluated(selectexpr, me);
    var target = me.getContainer().getElementById('xml');
    var targetDoc = target.getXmlDocument();
        
    if (me.outerNode.checked) {
        var xmlDoc = XmlDocument.create();
        if (isEntity) {
            xmlDoc.loadXML('<' + name + ' id="' + id + '" />');
        } else {
            xmlDoc.loadXML('<' + name + '>' + value + '</' + name + '>');
        }
                                            
        targetDoc.selectSingleNode(selectexpr).appendChild(xmlDoc.documentElement);
        target.setXml(targetDoc.xml);                
    } else {
        var expr = isEntity ? (selectexpr + '/' + name + '[@id=' + id + ']') : (selectexpr + '/' + name + '[. = "' + value + '"]');
        var node = targetDoc.selectSingleNode(expr);
        node.parentNode.removeChild(node);
        target.setXml(targetDoc.xml);
    }    
    
    if (refreshCanvas) {
        var values = targetDoc.selectNodes(selectexpr + '/' + name);
        var txt = '';
        for (var i=0; i < values.length; i++) {
            txt += (i == 0 ? '' : ', ') + values[i].firstChild.nodeValue;
        }
        refreshCanvas.innerHTML = txt;
    }
};

PRD.prototype.radioClicked = function(me, selectexpr, name, value, isEntity, refreshCanvas) {
    selectexpr = evaluated(selectexpr, me);
    var target = me.getContainer().getElementById('xml');
    var targetDoc = target.getXmlDocument();
        
    if (me.outerNode.checked) {
        var xmlDoc = XmlDocument.create();
        if (isEntity) {
            xmlDoc.loadXML('<' + name + ' id="' + id + '" />');
        } else {
            xmlDoc.loadXML('<' + name + '>' + value + '</' + name + '>');
        }
                                            
        targetDoc.selectSingleNode(selectexpr).appendChild(xmlDoc.documentElement);
        target.setXml(targetDoc.xml);                
    } else {
        var expr = isEntity ? (selectexpr + '/' + name + '[@id=' + id + ']') : (selectexpr + '/' + name + '[. = "' + value + '"]');
        var node = targetDoc.selectSingleNode(expr);
        node.parentNode.removeChild(node);
        target.setXml(targetDoc.xml);
    }    
    
    if (refreshCanvas) {
        var values = targetDoc.selectNodes(selectexpr + '/' + name);
        var txt = '';
        for (var i=0; i < values.length; i++) {
            txt += (i == 0 ? '' : ', ') + values[i].firstChild.nodeValue;
        }
        refreshCanvas.innerHTML = txt;
    }
};

PRD.prototype.fileChange = function(me, entity, width, height) {
    width = width ? width : '';
    height = height ? height : '';
    var win = me.getContainer().getElementById('uploader'); 
    win.open(); 
    win.center(); 
    prd.uploadinput = me.outerNode.previousSibling.previousSibling;
    window.frames['iframe' + entity].location = '../prd-runtime/upload.jsp?entity=' + entity + '&width=' + width + '&height=' + height;
}


function onupload(file) {
    var input = prd.uploadinput;
    input.value = file;
        
    if (input.nextSibling.tagName.toLowerCase() == 'img') {
        input.nextSibling.src = '../upload/' + file;
    } else {
        input.nextSibling.href = '../upload/' + file;
        input.nextSibling.innerHTML = file.substring(file.indexOf('!')+1);
    }
    
    var wrapped = application.wrapNode(input);
    //wrapped.sync();
    wrapped.dispatchChangeEvent();
    wrapped.getContainer().getElementById('uploader').close();
}

prd.filters = [];

PRD.prototype.setFilter = function(key, property, value, op) {    
    if (!prd.filters[key]) {
        prd.filters[key] = new Array();
    }
    if (value == '') {
        prd.filters[key][property] = null;
        return;
    }
    if (!op) {
        prd.filters[key][property] = [value];
    } else if (op < 0) {
        for (var i=prd.filters[key][property].length; i >=0 ; i--) {
            if (prd.filters[key][property][i] == value) {
                prd.filters[key][property].splice(i,1);                
            }
        }
    } else {
        if (!prd.filters[key][property]) {
            prd.filters[key][property] = [value];
        } else {
            prd.filters[key][property].push(value);
        }
    }
};

PRD.prototype.getFilters = function(key) {
    var url = '';
    for (var property in this.filters[key]) {    
    	// TODO escape filters
        if (property != 'toXMLRPC' && this.filters[key][property] && this.filters[key][property] != "0" && this.filters[key][property].length) {
                url += (property + '=' + this.getFiltersAsString(this.filters[key][property]) + ':');
        }
    }
    return url == '' ? '' : url.substring(0, url.length-1);
};

PRD.prototype.getFiltersAsString = function(array) {
    var string = '';
    for (var i=0; i < array.length; i++) {
        string += (i > 0 ? ',' : '') + array[i];
    }
    return string;
}

/*application.addEventListener('keydown', function(ev) {
    var target = ev.getTarget().getParentNode();

    if (ev.getKeyCode() == 37) {
        target.getParentNode().getChildNodes().item(target.getCellIndex()-1).getFirstChild().focus();        
    } else if (ev.getKeyCode() == 39) {
        target.getParentNode().getChildNodes().item(target.getCellIndex()+1).getFirstChild().focus();        
    } else if (ev.getKeyCode() == 38) {
        target.getParentNode().getParentNode().getChildNodes().item(target.getParentNode().getRowIndex()-1).getChildNodes().item(target.getCellIndex()).getFirstChild().focus();        
    } else if (ev.getKeyCode() == 40) {
        target.getParentNode().getParentNode().getChildNodes().item(target.getParentNode().getRowIndex()+1).getChildNodes().item(target.getCellIndex()).getFirstChild().focus();        
    }
});*/


PRD.prototype.registerPanelLink = function(me, a) {
    var xsl = prd.listingGetXsl(me.getChildContainer());
    xsl.addEventListener('click', 
        function(ev) { 
            var obj = ev.getTarget();
            while (xsl.getId() != obj.getId()) {
                if (obj.getAttribute('rowid')) {
                    var rowid = obj.getAttribute('rowid');
                    /*if (a) {
                        prd.openForm(me, 'Application', 'personCanvas', rowid);
                    } else {
                        prd.openListing(me, 'Application', 'applicationCanvas', 'forAd', 'forAd/' + rowid, true, function(container) {
                            prd.registerPanelLink(application.getElementById('applicationCanvas').getFirstChild(), true, null);
                            
                            //prd.openForm(me, 'Person', 'personCanvas', 
                            // function(me, entity, canvas, id) {
                        }, true);
                    }*/
                    application.getElementById('ticketCanvas').setInnerHTML('');
                    prd.openForm(me, 'Ticket', 'ticketCanvas', 'forGame/' + rowid, null, 'Sports', true);
                    break;
                }
                obj = obj.getParentNode();
                
                
            }
        }
    );
};

PRD.prototype.listingTabClick = function(me, entity) {
    var container = me.getContainer();
    var tab = me.getChildNodes().item(me.getSelectedIndex());
    
    if (tab.getAttribute('restriction')) {
        this.setFilter(container.getPrefix(), '_saved', tab.getAttribute('restriction'));
    } else  {
        this.setFilter(container.getPrefix(), '_saved', '');
    }
    
    
    if (tab.getAttribute('view')) {
        container.getElementById('selectview').setSelectedIndex(tab.getAttribute('view'));
    } else {
        container.getElementById('selectview').setSelectedIndex(0);
    }

    //Get all filters
    var filters = this.getFilters(container.getPrefix());            
    /*if (tab.getAttribute('restriction')) {
        filters = (filters.length ? ( filters + ':') : '') + '_saved=' + tab.getAttribute('restriction');
    }*/
    
    var children = tab.getChildNodes();
    for (var i=0; i < children.getLength(); i++) {
        var child = children.item(i);

/*        window.status = child.getAttribute('baseurl') + (filters.length ? ( '!' + filters) : '');
        child.setUrl(child.getAttribute('baseurl') + (filters.length ? ( '!' + filters) : ''));
    */    
        if (container.getElementById('selectview').getSelectedIndex() == i) {
            /*child.refresh();*/
            this.refreshFilter(container);
            child.getStyle().display = '';
        } else {
            child.getStyle().display = 'none';                
        }
    }
};

PRD.prototype.listingSavedFilterRefresh = function(me) {
/*    this.removeSavedFilters(me);*/
    var t = me.getInnerHTML().split(';');
    var tabpane = me.getContainer().getElementById('tabpane');
    if (!tabpane) {
        return; 
    }
    var tabs = tabpane.getChildNodes();
    var j = 0;
    //Get saved filters tabs position
    for (;j<tabs.getLength();j++) {
        if (tabs.item(j).getAttribute('restriction')) {
            break;
        }
    }
    //Compare with existing tabs. If not present, it appends it
    for (var i=0; i < t.length; i++) {
        tabs = tabpane.getChildNodes();    
        if (!tabs.item(j+i) || !tabs.item(j+i).getAttribute('restriction')) {
            this.appendSavedFilter(me, t[i].split(',')[0], t[i].split(',')[1]);
        }
    }
    if (me.getAttribute('focusLast') == 'true') {
        tabpane.focusChild(j+i-1);    
    }
};

PRD.prototype.appendSavedFilter = function(me, title, restriction) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (!tabpane || me.getInnerHTML() == '') {
        return;
    }
    var node = tabpane.getFirstChild();
    tabpane.appendTab(node, title);
    tabpane.getLastChild().setAttribute('restriction',restriction); 
    var tabs = tabpane.getChildNodes();
    var id = 'xsl_1_' + tabs.getLength();
    var views = tabpane.getLastChild().getChildNodes();
    for (var i=0; i<views.getLength(); i++) {
        views.item(i).setId('xsl_' + (i+1) + '_' + tabs.getLength());
    }
}


PRD.prototype.removeSavedFilters = function(me) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (!tabpane || me.getInnerHTML() == '') {
        return;
    }
    var nodes = tabpane.getChildNodes();
    for (var i=nodes.getLength()-1; i>=0; i--) {
        if (nodes.item(i).getAttribute('restriction')) {
            tabpane.removeTab(i);
        }
    }
}


PRD.prototype.listingChangeView = function(me) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (tabpane) {
        tabpane.getChildNodes().item(tabpane.getSelectedIndex()).setAttribute('view',me.getSelectedIndex());    
    }
    var i = tabpane ? (parseInt(tabpane.getSelectedIndex()) + 1) : 1;
    for (var j=0; j < me.outerNode.options.length; j++) {
        var xsl = container.getElementById('xsl_' + (j+1) + '_' + i);
        xsl.getStyle().display = (j == me.getSelectedIndex()) ? '' : 'none';
        if (j == me.getSelectedIndex()) {
            this.refreshFilter(container);
//            xsl.refresh();
        }
    }
};                

PRD.prototype.listingGetXsl = function(container) {
    var tabpane = container.getElementById('tabpane');
    var i = tabpane ? (parseInt(tabpane.getSelectedIndex()) + 1) : 1;
    var view = container.getElementById('selectview');
    view = view == null ? 1 : (view.getSelectedIndex()+1);
    return container.getElementById('xsl_' + view + '_' + i);        
};


PRD.prototype.listingGetItems = function(container, type) {
    var tabpane = container.getElementById('tabpane');
    var i = tabpane ? (parseInt(tabpane.getSelectedIndex()) + 1) : 1;
    var view = container.getElementById('selectview');
    view = view == null ? 1 : (view.getSelectedIndex()+1);
    
    switch(type) {
        case 'thumbnails': 
            return prd.getElementsById(container.getPrefix() + 'thumbnails_' + view + '_' + i);
        case 'icons': 
            return prd.getElementsById(container.getPrefix() + 'icons_' + view + '_' + i);
        case 'basic': 
            return prd.getElementsById(container.getPrefix() + 'basic_' + view + '_' + i);
    } 
    
    return [];
};


PRD.prototype.listingGetTable = function(container) {
    var tabpane = container.getElementById('tabpane');
    var i = tabpane ? (parseInt(tabpane.getSelectedIndex()) + 1) : 1;
    var view = container.getElementById('selectview');
    view = view == null ? 1 : (view.getSelectedIndex()+1);
    return container.getElementById('table_' + view + '_' + i);        
};


PRD.prototype.page = function(me, page, total) {
    if (page <= total && page > 0) {
        var container = me.getContainer();
        var key = container.getPrefix();
        var xsl = prd.listingGetXsl(container);
        var filters = this.getFilters(key);
        xsl.setUrl(xsl.getAttribute('baseurl') + ',page' + page + (filters.length ? ('!' + filters) : '')); 
             
		// console
		var tx = prd.startConsole('Paging', false, 'green');
		
        xsl.refresh(function(param, xmlDoc, status) {
        	// console
        	prd.endConsole(tx)
        
			// check network error
        	if (status != 200) {
        		prd.startConsole('Network error', true, 'green');  
        		return;
        	}
        	
        	// check service error
        	if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        		prd.startConsole('Network error', true, 'red'); 
				if (xmlDoc != null && xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes()) {
					alert(xmlDoc.documentElement.childNodes[0].nodeValue);
				} else {
					alert('Unable to read');
				}
        		return; 
        	}

        	
        });
    }
};

PRD.prototype.pageList = function(obj, num, size) {
    var pages = application.wrapNode(obj);
    if (pages.getChildNodes().getLength() == 1) {
        for (var i=1, cell; i<=size; i++) {
            cell = document.createElement('option');
            cell.value = cell.innerHTML = i;    
            if (num == i) {
                cell.selected = "selected";
            }
            obj.appendChild(cell);
        }
        pages.removeChild(pages.getFirstChild());
    }
};

PRD.prototype.order = function(me, label, index) {
    var container = me.getContainer();
    var xsl = prd.listingGetXsl(container);
    var filters = this.getFilters(container.getPrefix());
    if (xsl.getAttribute('order') == index) {
    	index += 'd';
    }
    xsl.setUrl(xsl.getAttribute('baseurl') + ',page1' + (filters.length ? ('!' + filters) : '') + '$' + index);
    xsl.setAttribute('order', index);
    
    // console
    var tx = prd.startConsole('Ordering', false, 'green');
    
    xsl.refresh(function(i, xmlDoc, status) {
    	// end console
    	prd.endConsole(tx);
    	
    	// check network error
		if (status != 200) {
        	prd.startConsole('Network error', true, 'green');  
        	return;
       	}
        	
        // check service error
        if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        	prd.startConsole('Error', true, 'red'); 
			if (xmlDoc != null && xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes()) {
				alert(xmlDoc.documentElement.childNodes[0].nodeValue);
			} else {
				alert('Unable to read');
			}
        	return; 
        }

    }, 0);
};


PRD.prototype.filter = function(property, value, me, op) {    
    var container = me.getContainer();
    this.setFilter(container.getPrefix(), property, value, op);
    this.refreshFilter(container);
};

PRD.prototype.refreshFilter = function(container) {    
    var xsl = prd.listingGetXsl(container);
    var filters = this.getFilters(container.getPrefix());
    window.status = xsl.getAttribute('baseurl') + ',page1' + (filters.length ? ('!' + filters) : '');
    xsl.setUrl(xsl.getAttribute('baseurl') + ',page1' + (filters.length ? ('!' + filters) : ''));
    
    // start console
    var tx = prd.startConsole('Filtering', false, 'green');
    
    xsl.refresh(function() {
		// end console
		prd.endConsole(tx);
		
		// TODO if (network or service error) return error
    });
};

PRD.prototype.getScreenX = function(obj) {
	if (obj.getBoundingClientRect) {
		return obj.getBoundingClientRect().left;
	} else {
		// TODO firefox
		return 0;
	}
};

PRD.prototype.getScreenY = function(obj) {
	if (obj.getBoundingClientRect) {
		return obj.getBoundingClientRect().top;
	} else {
		// TODO firefox
		return 0;
	}
};

PRD.prototype.tooltipOn = function(me) {
    var tooltip = me.getAttribute('tooltip');
    var div = me.getContainer().getElementById('tooltip');
    div.getLastChild().setInnerHTML(tooltip);    
    var style = div.getStyle();
    
   
    var top = 0;
    var left = 0;
    var screenX = prd.getScreenX(me.outerNode);
    var screenY = prd.getScreenY(me.outerNode);
    var width = me.getWidth();
    var height = me.getHeight();
    
    style.display = '';
    
    // TODO take care of scrolling windows with clientWidth/Height
	// TODO clientHeight returns 0
    if (screenX + width + 50 < document.body.clientWidth) {
    	top = me.getRelativeY();
	    left = me.getRelativeX() + width + 5;
    } else /*if (screenY + height + 30 < document.body.clientHeight)*/ {
    	left = me.getRelativeX();
    	top = me.getRelativeY() + me.getHeight() + 3;
    } /*else {
   		left = me.getRelativeX();
    	top = me.getRelativeY() - div.getLastChild().getHeight() + 10;
    }*/
    
    style.top = top + 'px';
    style.left = left + 'px';
    
    
    style = div.getFirstChild().getStyle();
    style.height = div.getLastChild().getHeight() + 'px';
    style.width = div.getLastChild().getWidth() + 'px';

};

PRD.prototype.tooltipOff = function(me) {
    var div = me.getContainer().getElementById('tooltip');
    div.getStyle().display = 'none';
};



PRD.prototype.jsAction = function(me, name) {
    var container = me.getContainer();
    var ids = this.getIds(me);
    ///var listing = this.listingGetXsl(container);
    
    eval(name + '(me, ids);');
    //listing.refresh();
    return false;
}

PRD.prototype.getIdsAsString = function(me) {
    var ids = prd.getIds(me);
    var s = '';
    for (var i=0; i < ids.length; i++) {
        s += (i > 0 ? ',' : '') + ids[i];
    }
    return s.length ? s : '0';
}

PRD.prototype.getIds = function(me) {
    var container = me.getContainer();

    var type = container.getElementById('selectview').getValue();
    var table = prd.listingGetTable(container);
    var ids = new Array();

    if (type == 'table') {
        var selected = table.getSelectedRows();
        for (var i=0; i < selected.length; i++) {
            ids[ids.length] = table.getLastChild().getChildNodes().item(selected[i]).getAttribute('rowid');
        }
    } else {
        var items = prd.listingGetItems(container, type);
        for (var i=0; i<items.length; i++) {
            if(items[i].getAttribute('selected')=='true') {
                ids[ids.length] = items[i].getAttribute('rowid');
            }
        }
    }
    
    return ids;
}

PRD.prototype.listingMouseOverThumbnail = function(me) {
    me.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getStyle().display = 'inline';
};

PRD.prototype.listingMouseOutThumbnail = function(me) {
    me.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getStyle().display = 'none';
};

PRD.prototype.listingToggleThumbnail = function(me) {
    if (me.getAttribute('selected') == 'true') {
        me.setAttribute('selected','false');
        me.setClassName('listing_thumbnails');
    } else {
        me.setAttribute('selected','true');        
        me.setClassName('listing_thumbnails listing_highlight');        
    }
}

PRD.prototype.listingToggleIcon = function(me) {
    if (me.getAttribute('selected') == 'true') {
        me.setAttribute('selected','false');
        me.setClassName('listing_icons');
    } else {
        me.setAttribute('selected','true');        
        me.setClassName('listing_highlight');        
    }
}

PRD.prototype.listingToggleBasic = function(me,odd) {
    if (me.getAttribute('selected') == 'true') {
        me.setAttribute('selected','false');
        me.setClassName(odd ? 'basic_odd' : 'basic_even');
    } else {
        me.setAttribute('selected','true');        
        me.setClassName('listing_highlight');        
    }    
}

PRD.prototype.showSaveFilter = function(me) {
    var container = me.getContainer();
    
    container.getElementById('saveFilterPanel').getStyle().display='';
    container.getElementById('saveFilterLink').getStyle().display='none';        
    container.getElementById('saveFilterInput').focus();
}
PRD.prototype.saveFilter = function(me) {
    var container = me.getContainer();
    container.getElementById('saveFilterPanel').getStyle().display='none';    
    container.getElementById('saveFilterLink').getStyle().display='';
    
    var xsl = prd.listingGetXsl(container);
    var name = me.getPreviousSibling().getValue();
    var filters = this.getFilters(container.getPrefix());
    
    /*this.setFilter(container.getPrefix(), '_saved', '');        */
    xsl.setUrl(xsl.getAttribute('baseurl') + ',saveas=' + name + (filters.length ? ('!' + filters) : ''));
    xsl.refresh(function() {
    	// TODO if (network or service error) return error
    
        container.getElementById('othertabs').setAttribute('focusLast','true');
        container.getElementById('othertabs').refresh(
        	// TODO if (network or service error) return error
        );
    });    
}

PRD.prototype.listingRemove = function(me, name) {
    if (confirm('Seguro de eliminar estos elementos?')) {
        var ids = this.getIds(me);
                        
        var container = me.getContainer();    
        container.getElementById('xmlrpcserver').executeAsync(name + '.remove', function(id, e) {
            if (e) {
                alert('No se puede borrar');
            } else {
                prd.refreshFilter(container);
            }
        }, ids);
        
    }
    return false;
    
    
}

PRD.prototype.getParam = function(param, def) {
    var url = window.location.search.toString().substring(1);
    var params = url.split('&');
    for (var i=0; i < params.length; i++) {
        var parameter = params[i].split("=");
        
        if (parameter[0] == param) {
            return parameter[1];        
        }
    }
    
    return def;
};

PRD.prototype.editGoogleDoc = function(me, docId) {
    if (!docId) {
    	var email = 'prodatest';
    	var pass = 'prodatest1';
        // auth
        var httpRequest = HttpRequest.create();
        httpRequest.open("POST", "https://www.google.com/accounts/ClientLogin", true);
        httpRequest.onreadystatechange = function() {
            if (httpRequest.readyState == 4) {
                var auth = httpRequest.responseText.split('\n')[2];
               // alert(httpRequest.responseText);
                // create doc
                var docRequest = HttpRequest.create();
                docRequest.open("GET", "http://docs.google.com/MiscCommands?command=newdoc&title=", true);
                docRequest.onreadystatechange = function() {
                    if (docRequest.readyState == 4) {
                        docId = docRequest.responseText;                        
                        
                        // sync
                        var input = me.getNextSibling();
                        input.setValue(docId);
                        input.dispatchChangeEvent();
                        //input.sync();
                        
                        // edit
                        window.open("http://docs.google.com/Doc?docid=" + docId, "_blank", "width=700,height=500,resizable=yes");
                    }
                };
              //  alert(auth);
                var value = auth.split('=')[1];
                docRequest.setRequestHeader("Authorization", " GoogleLogin " + "auth=" + value);
                docRequest.send("");
            }
        };
        httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        httpRequest.send("accountType=GOOGLE&Email=" + email + "&Passwd=" + pass + "&service=writely&source=proda-test-1");
                    

    } else {
        window.open("http://docs.google.com/Doc?docid=" + docId, "_blank", "width=700,height=500,resizable=yes");
    }
    
};


PRD.prototype.maskValidation = function(me, ev, escapedchars){

    if((ev.getKeyCode() >= '37' && ev.getKeyCode() <= '40') || ev.getKeyCode() == '13' || ev.getKeyCode() == '32'){
        return true;
    }
    
    var r = document.selection.createRange();
    
    if(ev.getKeyCode() == '8'){
        r.moveStart('character', -1);
        r.select();

        if(!this.isEscapedChar(escapedchars, r.text)){
            r.text = '_';
            return false;
        } else {
            r.move('character', 0)
            r.select();
            return false;
        }
    }
    
    r.moveStart('character', 0);
    r.moveEnd('character', 1);
    r.select();
    
    
    if(this.isEscapedChar(escapedchars, r.text )){
        if(r.findText('_')){
            r.collapse();
            r.select();
        } else {
            r.move('character', 1);
            r.collapse();
            r.select();
            return false;
        }
    }

}

PRD.prototype.isEscapedChar = function(escapedchars, char){
    for(var i=0; i < escapedchars.length; i++){
        if(char == escapedchars[i]){
            return true;
        }
    }
    return false;
}

PRD.prototype.setMask = function(me) {
    if (!me.getValue()) {
        me.setValue(me.getAttribute('mask'));
    }
}

PRD.prototype.selectTimeSync = function(me) {
	var children = me.getParentNode().getChildNodes();
	var input = children.item(3);
	var s1 = children.item(0).outerNode;
	var s2 = children.item(2).outerNode;
	input.setValue(s1.options[s1.selectedIndex].text + ':' + s2.options[s2.selectedIndex].text);
	input.sync();
};

PRD.prototype.selectDateSync = function(me) {
	var children = me.getParentNode().getChildNodes();
	var input = children.item(5);
	var s1 = children.item(0).outerNode;
	var s2 = children.item(2).outerNode;
	var s3 = children.item(4).outerNode;
	input.setValue(s1.options[s1.selectedIndex].text + '/' + s2.options[s2.selectedIndex].text + '/' + s3.options[s3.selectedIndex].text);
	input.sync();
};


PRD.prototype.auditHistory = function(me, entity) {
	var id = me.getContainer().getElementById('xml').getXmlDocument().selectSingleNode('/*/@id').nodeValue;
	window.open('../prd-runtime/history.jsp?entity=' + entity + '&id=' + id, entity, 'resizable=yes,status=no,scrollbars=yes,width=500,height=300');
};


PRD.prototype.startAsyncConsole = function(container, key, service) {
	var win = container.getElementById('console');
	var consoletxt = container.getElementById('consoletxt');
	win.open();
	var message = "";
	
	var callServer = function(key) {
		application.getElementById('xmlrpcserver').executeAsync(service + '.getMessage', function(result) {
			message = message + result;
			consoletxt.setValue(message);
			consoletxt.outerNode.scrollTop = consoletxt.outerNode.scrollHeight;
			if (result.indexOf('%END%') == -1) {
				setTimeout(function() {callServer(key)}, 1000);
			}
		}, parseInt(key));
	};
	
	callServer(key);	
};
		
var zoom = 1;
    
/*    document.onkeypress = function() {
        if (event.keyCode == 45) {
            zoom = zoom * 1/1.33;
        } else if (event.keyCode == 43) {
            zoom = zoom * 1.33;
        }  
        application.getElementById('window').getStyle().zoom = zoom;
    };
    */
    
    