com_htmli_ui_Source.cache = false; 
com_htmli_forms_Input.dontDispatchChangeEvent = true;

function JRapid() {
    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);
	}
};


JRapid.SERVER_PATH = '../xml/';

JRapid.prototype.getServerPath = function(container, def) {
	if (def) {
		container.node.setAttribute('serverPath', def);
	}
	//var path = container.node.getAttribute('serverPath');
	//return path ? path : JRapid.SERVER_PATH;
	return JRapid.SERVER_PATH;
};

JRapid.prototype.nextreport = function(key, me) {
	window.open('../report/' + me.getAttribute('report') + '?' + key + (me.getAttribute('pdf') ? '&pdf=pdf' : ''), '_blank', 'width=700,height=600,resizable=yes');
};

JRapid.prototype.nextfunction = function(key, me) {
	eval(me.getAttribute('function') + '(key, me)');
};

JRapid.prototype.nextpanel = function(key, me) {
	window.location = me.getAttribute('panel') + '.htmli';
};

JRapid.prototype.nextform = function(key, me) {
	jrapid.openForm(me, me.getAttribute('entity'), 'formcanvas', key, me.getAttribute('defaultset'));    
};

/**
 * Calls store method in the backend with the current data of the form 
 * 
 * @param me		object, the wrapped object placed in the container of the form
 * @param handler	function, callback executed after storing the entity
 * @param isAsync 	boolean, opens console for asynchronic calls
 * @param entity	string, name of the entity
*/
JRapid.prototype.store = function(me, handler, isAsync, entity) {
    this.apply(me, function(key) {
    	if (handler) {
	        handler(key, me);
		}
		if (isAsync) {
			jrapid.startAsyncConsole(me.getContainer(), key, entity);
		}
		if (me.getContainer().getElementById('xml').getAttribute('repeat')) {
	        jrapid.loadForm(me.getContainer(), entity, '0', null, false, null, null, null, true);
        }        
		
    });
}


/**
 * Opens an entity form, referencing current listing for further actions (e.g. refresh after store)
 * 
 * @param me				object, the wrapped object placed in the container of the listing
 * @param entity			string, name of the entity to be opened
 * @param canvas 			string, id of the HTML element used as canvas for opening window
 * @param defaultsetparams	string, comma-separated list of F-Path parameters sent to the specified defaultset
 * @param defaultset		string, defaultset to use when opening
 * @param module			string, module to which the opened entity belongs	
*/
JRapid.prototype.openFormFromListing = function(me, entity, canvas, defaultsetparams, defaultset, module) {

	var id = jrapid.evaluateIfNotNull(defaultsetparams, me, '0');
	if (defaultsetparams && (id == '0' || id == '')) {
		if (confirm('It is necessary to save before continuing. Save now?')) {
			var submit = me.getContainer().getParent().getElementById('submit');
			jrapid.apply(submit, function(newId) {
				jrapid.openForm(me, entity, canvas, newId, defaultset, module);
				var xml = submit.getContainer().getElementById('xml');
				if (xml.getAttribute('baseurl')) {
					xml.setUrl(xml.getAttribute('baseurl') + '/' + newId);				
					var path = xml.getAttribute('entity');
					path = path == null || path.length == 0 ? path : path.substring(0,1).toLowerCase() + path.substring(1);
					path = '/' + path + '/@id';
    				if (xml.outerNode.triggers && xml.outerNode.triggers[path]) {
						for (var i=0; i < xml.outerNode.triggers[path].length; i++) {
							xml.outerNode.triggers[path][i].execute(null, submit);
				        }
				    } 
				}
			}, null, null, true);
        }
	} else {
		jrapid.openForm(me, entity, canvas, id, defaultset, module);
	}
	return false;
};

JRapid.prototype.cancel = function(me) {
    var container = me.getContainer();
    container.getElementById('window').close();
    container.close();
}

var c;
/********************** validations ***************************/

JRapid.validations = [];
JRapid.validations['required'] = function(obj) { return obj.value && (obj.tagName.toLowerCase() != 'select' || obj.value != '0') ? null : (obj.title + ' is required'); };
JRapid.validations['date'] = function(obj) { return obj.value == '' || obj.value.match(jrapid.dateRegExp) ? null : (obj.title + ' is a date'); };
JRapid.validations['datetime'] = function(obj) { return obj.value == '' || obj.value.match(jrapid.dateTimeRegExp) ? null : (obj.title + ' is datetime'); };
JRapid.validations['time'] = function(obj) { return obj.value == '' || obj.value.match(jrapid.timeRegExp) ? null : (obj.title + ' is time'); };
JRapid.validations['timequantity'] = function(obj) { return obj.value == '' || obj.value.match(jrapid.timeQuantityRegExp) ? null : (obj.title + ' is timequantity'); };
JRapid.validations['timerange'] = function(obj) { return obj.value == '' || obj.value.match(jrapid.timeRangeRegExp) ? null : (obj.title + ' is timerange'); };
JRapid.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 + ' is email');};
JRapid.validations['short'] = function(obj) { return obj.value == '' || obj.value.match(/^\-?[0-9]+$/) ? null : (obj.title + ' is short'); };
JRapid.validations['integer'] = function(obj) { return obj.value == '' || obj.value.match(/^\-?[0-9]+$/) ? null : (obj.title + ' is integer'); };
JRapid.validations['long'] = function(obj) { return obj.value == '' || obj.value.match(/^\-?[0-9]+$/) ? null : (obj.title + ' is long'); };
JRapid.validations['float'] = function(obj) { return obj.value == '' || obj.value.match(/^\-?[0-9]+(\.[0-9]+)?$/) ? null : (obj.title + ' is float'); };
JRapid.validations['double'] = function(obj) { return obj.value == '' || obj.value.match(/^\-?[0-9]+(\.[0-9]+)?$/) ? null : (obj.title + ' is double'); };

JRapid.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 (JRapid.validations[validations[j]]) {
                var errorMessage = JRapid.validations[validations[j]](element);
                if (errorMessage) {
                    msg += errorMessage + ' - ';
                    hasErrors = true;                
                }
            }            
        }
        element.style.color = hasErrors ? 'red' : '';
        window.status = msg;
    }    
};

JRapid.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 (JRapid.validations[validations[j]]) {
                    var errorMessage = JRapid.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 *****************************/

/**
 * Calls store method in the backend with the current data of the form 
 * 
 * @param me			object, the wrapped object placed in the container of the form
 * @param handler		function, callback executed after storing the entity
 * @param confirmed		string, comma-separated list of confirmed values
 * @param prompted		string, comma-separated list of prompted values
 * @param doNotClose	boolean, preserves the current form window opened
*/
JRapid.prototype.apply = function(me, handler, confirmed, prompted, doNotClose) {

    var container = me.getContainer();
    var xml = container.getElementById('xml');
    me.setDisabled(true);
    jrapid.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 (jrapid.hasErrors.length || !this.validate(container.getElementById('form').outerNode)) {
        if (jrapid.hasErrors.length) {
            alert(jrapid.hasErrors);
        }
        me.setDisabled(false);
        return false;
    }

    
    // confirmation handling
    this.setConfirmedAndPrompted(xml, confirmed, prompted);
    
    // set timeout
    var t;
    if (jrapid.timeoutSeconds) {
        var timeout = function() {
                //jrapid.endTransaction(transactionId);
        	if (t && !confirm(jrapid.timeoutSeconds + ' seconds have passed. \n\nPlease verify your Internet connection.\n\nKeep waiting?')) {
                me.setDisabled(false);
                xml.abort();
            } else if (t) {
                t = setTimeout(timeout, jrapid.timeoutSeconds*1000);
            }
        };
        t = setTimeout(timeout, jrapid.timeoutSeconds*1000);
    }
    
    // init transation
    var tx = jrapid.startConsole('Applying', false, 'green');
  
    // send the post
    xml.post(function(xmlDoc, status) {
    
    	// end console
    	jrapid.endConsole(tx);    		
   	
        // clear timeout
        if (t) { clearTimeout(t); t = null; }
        
		// check network error
		if (status != 200) {
			me.setDisabled(false);
			jrapid.startConsole('Network error', true, 'red');
			return false;
		}
    
        // do the work
        if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
            me.setDisabled(false); 
            jrapid.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') {
            jrapid.startConsole('Confirm', true, 'yellow');
            if (confirm(xmlDoc.documentElement.childNodes[0].nodeValue)) {
                return jrapid.apply(me, handler, (confirmed ? (confirmed+',') : '') + xmlDoc.documentElement.getAttribute('code'));
            } else {
                me.setDisabled(false);
                return;
            }
        } else if (xmlDoc.documentElement.tagName == 'prompt') {
            jrapid.startConsole('Prompt', true, 'yellow');
            var value;
            if (value = prompt(xmlDoc.documentElement.childNodes[0].nodeValue, '')) {
                return jrapid.apply(me, handler, confirmed, (prompted ? (prompted+',') : '') + xmlDoc.documentElement.getAttribute('code') + '=' + value);
            } else {
                me.setDisabled(false);
                return;
            }
        } 
        
        jrapid.startConsole('Saved', true, 'green');
        if (container.node && container.node.listingContainer) {
        	var xsl = jrapid.listingGetXsl(container.node.listingContainer);
        	if (xsl && xsl.refresh) {
        		xsl.refresh();
        	}
        }
        
		if (doNotClose) {
			var id =  xmlDoc.documentElement.childNodes[0].nodeValue;
			var oldDoc = xml.getXmlDocument();
			oldDoc.selectSingleNode('/*').setAttribute('id', id);
			xml.setXml(oldDoc.xml);
			me.setDisabled(false);
		}

        if (handler) {
            handler(xmlDoc.documentElement && xmlDoc.documentElement.hasChildNodes() ? xmlDoc.documentElement.childNodes[0].nodeValue : null);
        }
        
        try { 
        	if (!doNotClose && !xml.getAttribute('repeat')) {
        		container.close();        		
			}
		} catch (e) {
	    }
		me.setDisabled(false);
        
    });
    
};

JRapid.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 jrapid = new JRapid();
var prd = new JRapid();

function evaluated(path, row) {
try {
	var n=-1;
    var newPath = '';
  	for (var i=0; i < path.length; i++) {
		var c = path.charAt(i);
		if (c == '(' || c == ')' || c == ',' || c == ' ') {
			newPath += evaluatedPart(path.substring(n+1, i), row) + path.charAt(i);
			n = i;
		}
	}
	if (n != path.length-1) {
		newPath += evaluatedPart(path.substring(n), row);
	}
			
			
			} catch (e) {throw e; alert(e.message); }
/*
	// TODO check all separators
    var parts = path.split(new RegExp('(\\(|\\)|\\s+|,)'));
    //var parts = /(\\(|\\)|\\s+|,)/i.exec(path);
    var newPath = '';
    for (var i=0; i < parts.length; i++) {
       newPath = newPath + evaluatedPart(parts[i], row);	
	}	
	alert(newPath);*/
	return newPath;
}

function evaluatedPart(path, row) {
    if (row.outerNode) {
        row = row.outerNode;
    }
    //Cross-browser fix
	var partsBracket = path.split(new RegExp('(\\[|\\])'));
	var parts = [];
	for (var i=0, j=0; i < partsBracket.length; i++) {
		if (partsBracket[i]!='[' && partsBracket[i]!=']') {
			parts[j++] = partsBracket[i]
		}
	}
		
    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;
}

JRapid.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;
}


JRapid.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"  exclude-result-prefixes="xslt xslt2">';
    xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
    xsl += '<xslt:output method="xml" omit-xml-declaration="yes" /><xslt:template match="/"><out>';
    xsl += '<xslt:choose><xslt:when test="' + xpath + '">1</xslt:when><xslt:otherwise>0</xslt:otherwise></xslt:choose>';
    xsl += '</out></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();

   	var str = xmlDoc.transformNode(xslDocument).substring(5);
    return str.substring(0,str.length-6) == '1';
}
 

JRapid.prototype.initialTriggers = function(me) {
	setTimeout(function() {
	    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);
    	    }
	    }
	}, 1);
};

JRapid.prototype.trigger = function(fpath, me) {
    setTimeout(function() {
        jrapid.triggerWrapped(fpath, me);
    }, 1);
};

JRapid.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);
        }
    }                                
};

JRapid.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 = jrapid.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]);
    }    
};

JRapid.prototype.registerInitialTrigger = function(prefix, trigger) {
    var xml = document.getElementById(prefix + 'xml');
    
    if (xml.triggers == null) {
        xml.triggers = new Array();
    }
        
    if (xml.triggers['main'] == null) {
        xml.triggers['main'] = new Array();
    }
    
    xml.triggers['main'][xml.triggers['main'].length] = trigger;    
};

JRapid.prototype.registerCalculatedProperty = function(prefix, slaveFpath, slaveId, calculus, triggers, triggerMode) {
	if (triggerMode != 'onload') {
	    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
	        array[index] = new JRapid_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, trigger, triggerMode);
	    });    
	}
    if (!triggerMode || triggerMode == 'onload') {
	    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, null, triggerMode));
	}
};

JRapid.prototype.registerSubsetParams = function(prefix, slaveFpath, slaveId, params, subset, triggers, whenNotInSubset) {
    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_SubsetParams(slaveFpath, slaveId, params, trigger, subset, whenNotInSubset);
    });
    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_SubsetParams(slaveFpath, slaveId, params, null, subset, whenNotInSubset));
    var xml = document.getElementById(prefix + 'xml');
    if (!xml.subsetParams) {
        xml.subsetParams = [];
    }
    xml.subsetParams[slaveId] = params;
};

JRapid.prototype.registerIf = function(prefix, slaveFpath, slaveId, condition, triggers, func, applyToCanvas, triggerOnApply) {

    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_If(slaveFpath, slaveId, condition, trigger, func, applyToCanvas);
    });
    if (func != jrapid.checkIf) {
        jrapid.registerInitialTrigger(prefix, new JRapid_Registration_If(slaveFpath, slaveId, condition, null, func, applyToCanvas));
    }
    if (triggerOnApply) {
        jrapid.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
            array[index] = new JRapid_Registration_If(slaveFpath, slaveId, condition, null, func, applyToCanvas);
        });
    }
};

JRapid.prototype.registerCondition = function(prefix, slaveFpath, slaveId, params, triggers, func, rpcService, applyToCanvas) {
    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_Condition(slaveFpath, slaveId, params, trigger, func, rpcService, applyToCanvas);
    });
    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_Condition(slaveFpath, slaveId, params, null, func, rpcService, applyToCanvas));
    /* async problems, apply() can be called before this, causing unwanted behaviour 
    if (func == jrapid.checkUnique) {
        jrapid.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
            array[index] = new JRapid_Registration_Condition(slaveFpath, slaveId, params, null, func, rpcService);
        });
    }*/
};

JRapid.prototype.registerDynamicValue = function(prefix, slaveFpath, slaveId, params, triggers, rpcService, triggerMode) {
	if (triggerMode != 'onload') {
	    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
	        array[index] = new JRapid_Registration_DynamicValue(slaveFpath, slaveId, params, trigger, rpcService, triggerMode);
	    });
	}
    if (!triggerMode || triggerMode == 'onload') {
	    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_DynamicValue(slaveFpath, slaveId, params, null, rpcService, triggerMode));
	}
};

JRapid.prototype.registerDynamicForEach = function(prefix, slaveFpath, slaveId, params, triggers, service, fullXpath, triggerMode) {
	// TODO implement other trigger modes
    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_DynamicForEach(slaveFpath, slaveId, params, trigger, service, fullXpath, triggerMode);
    });
    if (!triggerMode || triggerMode == 'onload') {
		jrapid.registerInitialTrigger(prefix, new JRapid_Registration_DynamicForEach(slaveFpath, slaveId, params, null, service, fullXpath));
	}
};

JRapid.prototype.registerEmbeddedListing = function(prefix, slaveId, entity, params, triggers, subset, listing, name, containerEntity, module, defaultset, defaultsetparams) {
    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_EmbeddedListing(slaveId, params, trigger, entity, subset, listing, name, containerEntity, module, defaultset, defaultsetparams);
    });
    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_EmbeddedListing(slaveId, params, null, entity, subset, listing, name, containerEntity, module, defaultset, defaultsetparams));
};

JRapid.prototype.registerRichText = function(prefix, id) {
    jrapid.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
        array[index] = new JRapid_Registration_RichText(id, 'save');
    });
    jrapid.registerInitialTrigger(prefix, new JRapid_Registration_RichText(id, 'read'));
};

JRapid.prototype.registerCheckIf = function(prefix, id, constraint, triggers, message) {
    jrapid.registerAbstract(prefix, triggers, function(array, index, trigger) {
        array[index] = new JRapid_Registration_CheckIf(id, constraint, trigger, message);
    });
    jrapid.registerAbstract(prefix, '__onapply', function(array, index, trigger) {
        array[index] = new JRapid_Registration_CheckIf(id, constraint, trigger, message);
    });
};
        
function JRapid_Registration_CalculatedProperty(slaveFpath, slaveId, calculus, trigger, triggerMode) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.calculus = calculus;
    this.trigger = trigger;
    this.triggerMode = triggerMode;
};

function JRapid_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 JRapid_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 JRapid_Registration_Condition(slaveFpath, slaveId, params, trigger, func, rpcService, applyToCanvas) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.func = func;
    this.rpcService = rpcService;
    this.applyToCanvas = applyToCanvas;
};

function JRapid_Registration_DynamicValue(slaveFpath, slaveId, params, trigger, rpcService, triggerMode) {
    this.slaveFpath = slaveFpath;
    this.slaveId = slaveId;    
    this.params = params.length ? params.split(';') : [];
    this.trigger = trigger;
    this.rpcService = rpcService;
    this.triggerMode = triggerMode;
};

function JRapid_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 JRapid_Registration_EmbeddedListing(slaveId, params, trigger, entity, subset, listing, name, containerEntity, module, defaultset, defaultsetparams) {
    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;
    this.defaultsetparams = defaultsetparams;
};

function JRapid_Registration_RichText(id, action) {
    this.id = id;
    this.action = action;
};

function JRapid_Registration_CheckIf(constraint, trigger, message) {
    this.constraint = constraint;
    this.trigger = trigger;
    this.message = message;
}

JRapid.prototype.replaceAll = function(string, pattern, replacement) {
    while (string.match(pattern)) {
        string = string.replace(pattern, replacement);
    }
    return string;
};

JRapid.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;
};

JRapid_Registration_SubsetParams.prototype.execute = function(evaluatedPath, me) {
    try {
        
        var container = me.getContainer();
        var xsl = container.getElementById('window_subset_' + this.slaveId);
        var xmlmultiple = xsl.getPreviousElementSibling();
        var xml = xmlmultiple.getFirstElementChild();
        xmlmultiple.getLastElementChild().setXml(container.getElementById('xml').getXmlDocument().xml);
        var ud = this.slaveId;
        var canvas = jrapid.getElementsById(container.getPrefix() + 'div_subset_' + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(jrapid.replaceAll(this.trigger, '_', '.'), canvas[i]);
            if (child == evaluatedPath) {
                var url = jrapid.getServerPath(container) + this.subset;
                for (var j=0; j < this.params.length; j++) {
                    url += '/' + jrapid.escapeParam(jrapid.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]));
                }
                var whenNotInSubset = this.whenNotInSubset;
				xml.setUrl(url);
                
                xml.get(function(c) { 
                    xsl.refresh();
                    
                    var disabled;
                    var option;
                    var value;
                    
                    if (c.children.length) {
                    	var obj = c.children[0];
	                    disabled = obj.disabled;
    	                option = obj.options && obj.selectedIndex >= 0 ? obj.options[obj.selectedIndex] : null;
        	            value = obj.value;
					}
					c.innerHTML = xsl.getInnerHTML(); 
                
                    if (c.children.length) {
	                    c.children[0].disabled = disabled;
	                    c.children[0].value = value;
	                    if (option && value != c.children[0].value && whenNotInSubset != 'donotshow') {
	                        if (whenNotInSubset == 'shownotvalid') {
	                            option.style.color = 'red';
	                        }
	                        c.children[0].options[c.children[0].options.length] = option;
	                        option.selected = true;
	                    }
	                }
                    //this.setValue();
                }, canvas[i]);            
            }
        }
    } catch (e) {
       throw e;
    }
}

JRapid.prototype.getSubsetParams = function(me, slaveId) {
    var xml = document.getElementById(me.getContainer().getPrefix() + 'xml');
    if (xml.subsetParams && xml.subsetParams[slaveId]) {
        return xml.subsetParams[slaveId];
    }       
    return '';
};

JRapid_Registration_CalculatedProperty.prototype.execute = function(evaluatedPath, me) {
    try {
        var container = me.getContainer();
        var canvas = jrapid.getElementsById(container.getPrefix() + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
			if (this.triggerMode == 'onchangenew' && canvas[i].value) {
				continue;
			}
            var child = evaluatedPath == null ? null : evaluated(jrapid.replaceAll(this.trigger, '_', '.'), canvas[i]);
            var currentStyle = canvas[i].parentNode.currentStyle ? canvas[i].parentNode.currentStyle : window.getComputedStyle(canvas[i].parentNode,null);            
                
            if (currentStyle.color != 'green' && (child == evaluatedPath || evaluatedPath.match(child.replace(/\[/g, '\\[').replace(/\]/g, '\\]')))) {
               	if (!jrapid.isNewOrHidden(canvas[i])) {
                    var value = jrapid.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>');
}

JRapid_Registration_If.prototype.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    var canvas = jrapid.getElementsById(container.getPrefix() + (this.applyToCanvas ? 'td_': '') + this.slaveId);
    for (var i=0; i < canvas.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(jrapid.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);
            }                    
        }
    }
}

JRapid.prototype.displayIf = function(obj, bool) {
    obj.style.display = (bool ? '' : 'none');
};

JRapid.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);
    }
};


JRapid.prototype.visibleIf = function(obj, bool) {
    obj.style.visibility = (bool ? '' : 'hidden');
};

JRapid.prototype.readonlyIf = function(obj, bool) {
    obj.readOnly = bool;
};

JRapid.prototype.disabledIf = function(obj, bool) {
    obj.disabled = bool;
};

JRapid.prototype.checkIf = function(obj, bool, msg) {
    if (!bool) {
        jrapid.hasErrors += (msg?msg:'Invalid value') + '\n';
    }
    obj.style.backgroundColor = bool ? '': 'red';
};

JRapid.prototype.checkUnique = function(obj, isUnique) {
    if (isUnique != null && !isUnique) {
        alert('This field is not unique. ');
        jrapid.hasErrors += 'This field is not unique. ';
    }
    obj.style.backgroundColor = isUnique == null || isUnique ? '': 'red';
};


JRapid_Registration_Condition.prototype.execute = function(evaluatedPath, me) {

    var container = me.getContainer();
    var canvas = jrapid.getElementsById(container.getPrefix() + (this.applyToCanvas ? 'td_': '') + this.slaveId);
    var params = [];
	var x = [];

    for (var i=0; i < canvas.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(jrapid.replaceAll(this.trigger, '_', '.'), canvas[i]);
        if (child == evaluatedPath) {
            var paramsString = '';
            params[i] = [];
            for (var j=0; j < this.params.length; j++) {
                params[i][params[i].length] = jrapid.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]);
                paramsString += ',params[' + i + '][' + j + ']';
            }
            if (this.applyToCanvas && canvas[i].parentNode.getAttribute('labelposition') == 'top') {
                x[i] = canvas[i].parentNode;
                //this.func(canvas[i].parentNode.previousSibling, value);                
            } else if (this.applyToCanvas && !canvas[i].parentNode.getAttribute('row')) {
                x[i] = canvas[i].parentNode;
            } else {
				x[i] = canvas[i];
            }  
            var xmlrpcserver = container.getElementById('xmlrpcserver');
            var func = this.func;
            eval('xmlrpcserver.executeAsync(this.rpcService, function(r) { func(x[' + i + '], r); }' + paramsString + ')');    
        }
    }    
}


JRapid_Registration_DynamicValue.prototype.execute = function(evaluatedPath, me) {

    try {
	    var container = me.getContainer();
        var canvas = jrapid.getElementsById(container.getPrefix() + this.slaveId);
        for (var i=0; i < canvas.length; i++) {
            var child = evaluatedPath == null ? null : evaluated(jrapid.replaceAll(this.trigger, '_', '.'), canvas[i]);
            if (this.triggerMode == 'onchangenew' && canvas[i].value) {
        		continue;
        	}
            var currentStyle = canvas[i].parentNode.currentStyle ? canvas[i].parentNode.currentStyle : window.getComputedStyle(canvas[i].parentNode,null);
            
        	if (currentStyle.color != 'green' && (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] = jrapid.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, e) {  if (e) { } else { setDynamicValue(canvas[' + i + '], r);}} ' + p + ')');
            }
        }
    } catch (e) {
        throw e;
    }
    
}

JRapid_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);
};

JRapid_Registration_DynamicForEach.prototype.execute = function(evaluatedPath, me) {

    try {
        var container = me.getContainer();
	    var prefix = container.getPrefix();
        var canvas = jrapid.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(jrapid.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] = jrapid.evaluateXpath(evaluated(this.params[j], canvas[i]), canvas[i]);
                    p += '/' + params[j];
                }
                var x = canvas[i];
                
				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;
                        var elementName = fullXpath.substring(fullXpath.lastIndexOf('/')+1);
                        for (var k=0; k < n; k++) {
                            if (!newNodes[k].attributes) {
                                continue;
                            }
                       
                            // TODO importnode for ff3
                            var e = xml.createElement(elementName);
                            for (var l=0; l < newNodes[k].attributes.length; l++) {
                                var name = newNodes[k].attributes[l].name;
                                var value = newNodes[k].attributes[l].value;
                                e.setAttribute(name, value);
                            }
                            while (newNodes[k].hasChildNodes()) {
                                e.appendChild(newNodes[k].childNodes[0]);
                            }
                            parentNode.appendChild(e);
                        }
                       
                        // refresh html
                        container.getElementById('xml').setXml(multipleXml.selectSingleNode(xpath).xml);
                        x.innerHTML = multipleXml.transformNode(xslDocument);					
					}
				};
				xml.load(jrapid.getServerPath(container) + this.service + p);
            }
        }
    } catch (e) {
        throw e;
    }
    
}


JRapid_Registration_EmbeddedListing.prototype.execute = function(evaluatedPath, me) {

    var container = me.getContainer();
    var sources = jrapid.getElementsById(container.getPrefix() + this.slaveId);
    for (var i=0; i < sources.length; i++) {
        var child = evaluatedPath == null ? null : evaluated(jrapid.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 += '/' + jrapid.escapeParam(jrapid.evaluateXpath(evaluated(this.params[j], sources[i]), sources[i]));
                }
            }
            // TODO check when there are more than one defaultsetparam
			var defaultsetparams = this.defaultsetparams ? this.defaultsetparams.split(';')[0] : null;
            var defaultset = this.defaultset;
            if (sources[i].innerHTML == '') {
            	jrapid.openListing(me, this.entity, this.slaveId, this.listing, this.subset + params, true, function(c) {
            		c.getElementById('add').setAttribute('defaultset', defaultset);
	            	c.getElementById('add').setAttribute('defaultsetparams', defaultsetparams);
    	        }, true, '../forms.' + this.module + '/' + this.containerEntity + '_' + this.name + '_embeddedlist.htmli');
			} else {
				jrapid.loadListing(new Container(sources[i].children[0]), this.entity, this.subset + params, false);				
			}
        }
    }
}

JRapid_Registration_RichText.prototype.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    var riches = jrapid.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);
    }
        
};

JRapid_Registration_CheckIf.execute = function(evaluatedPath, me) {
    var container = me.getContainer();
    
    var value = evaluateBoolean(this.condition, me);

};

JRapid.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" exclude-result-prefixes="xslt xslt2">';
        xsl += '<xslt:namespace-alias stylesheet-prefix="xslt2" result-prefix="xslt"/>';
        xsl += '<xslt:output method="xml" omit-xml-declaration="yes" /><xslt:template match="/"><out>';
        xsl += m;
        xsl += '</out></xslt:template></xslt:stylesheet>';
        return xsl;
    }
    
    var parseResult = function(str) {
    	str = str.substring(5);
    	str = str.substring(0, str.length-6);
    	return str == 'NaN' ? '' : str;
    };
    
    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 parseResult(xmlDoc.transformNode(xslDocument));
    } catch (e) {
        xslDocument.async = false;
      	xslDocument.loadXML(buildXsl(xslSingle));
	return parseResult(xmlDoc.transformNode(xslDocument));
    }
};


JRapid.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;
    }
};

JRapid.prototype.openListing = function(me, entity, canvas, listing, subset, replace, handler, skipWindow, url, serverPath) {
    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);
    }
    
    // remember canvas for resizing
    if (canvas) {
		if (container.node) {
            container.node.canvas = container.getElementById(canvas);
        } else {
            application.canvas = container.getElementById(canvas);
        }
    }
    
    // console
    var txOpenListing = jrapid.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()) {
		   	jrapid.endConsole(txOpenListing);
	   		jrapid.startConsole('Network error', true, 'red');
	   		return;
    	}
    	
        var childContainer = sourcePrototype.getChildContainer();
        var xsl = jrapid.listingGetXsl(childContainer);
        xsl.getStyle().display = '';
        var baseurl = jrapid.getServerPath(childContainer, serverPath) + entity + (subset && subset.length > 0 ? ('/' + subset) : '');
        xsl.setUrl(baseurl + ',page1');
        xsl.setAttribute('baseurl', baseurl);
        xsl.setAttribute('entity', entity);
        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
        	jrapid.endConsole(txOpenListing);
        	
        	// check network error
        	if (status != 200) {
        		jrapid.startConsole('Network error', true, 'green');  
        		return;
        	}
        	
        	// check service error
        	if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        		jrapid.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();                
            }
        });
    });
        
    
};

JRapid.prototype.loadListing = function(container, entity, subset, openWindow, canvas, handler, serverPath) {
	// this method is only used from body.onload in *list

    var xsl = container.getElementById('xsl_1_1');
    var baseurl = jrapid.getServerPath(container, serverPath) + entity + (subset && subset.length > 0 ? ('/' + subset) : '');
    xsl.setUrl(baseurl + ',page1');
    xsl.setAttribute('baseurl', baseurl);
    xsl.setAttribute('entity', entity);
    
    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 = jrapid.startConsole('Loading listing', false, 'green');

    xsl.refresh(function() {
    	// TODO if (network or service error) return error
    
    	jrapid.endConsole(tx);
    	jrapid.startConsole('Listing ok', true, 'green');
    	
        if (openWindow) {
            var win = container.getElementById('window');
            win.open();
        }
        
        if (handler) {
        	handler();
        }        
        
    }, true);
}

JRapid.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 = jrapid.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) {
	
	}
};


JRapid.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() {
    jrapid.resizeTable(jrapid.listingGetXsl(me.getContainer())); }, 10);
};



JRapid.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 ? '/' : '') + jrapid.evaluateXpath(params[j], me);
        }
    }

    return jrapid.openListing(me, entity, 'formcanvas', listing, subset + (subset && id ? '/' : '') + id);
};


JRapid.prototype.openRelatedForms = function(me, entity, ids, defaultset) {
    for (var j=0; j < ids.length; j++) {
        jrapid.openForm(me, entity, 'formcanvas', ids[j], defaultset);
    }
};

JRapid.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 ? '/' : '') + jrapid.evaluateXpath(params[j], me);
        }
    }

    return jrapid.openForm(me, entity, 'formcanvas', id, defaultset);    
};


JRapid.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 = jrapid.startConsole('Opening form', false, 'green');
    
    sourcePrototype.open(function() {
    	// end console
    	jrapid.endConsole(txOpenForm);
    
    	if (!sourcePrototype.isOpened()) {
		    var tx = jrapid.startConsole('Network error', true, 'red');    		
		    return;
    	}
    
        var childContainer = sourcePrototype.getChildContainer();
        jrapid.loadForm(childContainer, entity, id, defaultset, !skipWindow);
    });
    sourcePrototype.getChildContainer().node.listingContainer = container;
    
};

JRapid.prototype.loadForm = function(container, entity, id, defaultset, openWindow, handler, confirmed, prompted, repeat, serverPath) {
	serverPath = jrapid.getServerPath(container, serverPath);

    var children = container.getElementById('xmlmultiple').getChildren();
    for (var i=0; i < children.getLength(); i++) {
        if (children.item(i).getAttribute('baseurl')) {
            children.item(i).setUrl(serverPath + children.item(i).getAttribute('baseurl'));
        }
    }
    
    var xsl = container.getElementById('xsl');
    var xml = container.getElementById('xml');
    xml.setUrl(serverPath + entity + '/' + (defaultset ? (defaultset + '/') : '') + id);
	xml.setAttribute('repeat', repeat ? 'repeat' : '');
	xml.setAttribute('baseurl', serverPath + entity + '/' + (defaultset ? (defaultset + '/') : '') );			
	xml.setAttribute('entity', entity);
	
	// confirmation handling
    this.setConfirmedAndPrompted(xml, confirmed, prompted);
    
    // console
	var tx = jrapid.startConsole('Loading', false, 'green');

    xml.setUrl(xml.getUrl() + '&' + new Date().getTime());    
    xsl.refresh(function(foo, xmlDoc, status) {
    	// end console
    	jrapid.endConsole(tx);

    	if (status != 200) {
    		alert('network error');
    		jrapid.startConsole('Network error', true, 'red');
    		return;
    	}
    	
    	var xmlDoc = xml.getXmlDocument();  
    	if (!JRapid.ignoreErrors) {  
    		if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
	            jrapid.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') {
	            jrapid.startConsole('Confirm', true, 'yellow');
	            if (confirm(xmlDoc.documentElement.childNodes[0].nodeValue)) {
	                return jrapid.loadForm(container, entity, id, defaultset, openWindow, handler, (confirmed ? (confirmed+',') : '') + xmlDoc.documentElement.getAttribute('code'));
	            } else {
	                return;
	            }
	        } else if (xmlDoc.documentElement.tagName == 'prompt') {
	            jrapid.startConsole('Prompt', true, 'yellow');
	            var value;
	            if (value = prompt(xmlDoc.documentElement.childNodes[0].nodeValue, '')) {
	                return jrapid.loadForm(container, entity, id, defaultset, openWindow, handler, confirmed, (prompted ? (prompted+',') : '') + xmlDoc.documentElement.getAttribute('code') + '=' + value);
	            } else {
	                return;
	            }
	        } 
	    	jrapid.startConsole('Opened ok', true, 'green');
		}   
        if (openWindow) {
            var win = container.getElementById('window');
            win.open();        
            /* Resize window with new contents size*/
            var xslDiv = container.getElementById('xsl');
            if (document.all) {
            	xslDiv.getStyle().display = 'inline';
            } else {
            	xslDiv.getStyle().position = 'absolute';
            	p = xslDiv;
            	while (p != null && p.getWidth) {
            		//alert(p.getWidth() + " " + p.getId());
            		p = p.getParentNode();
            	}
            }
            //xslDiv.getStyle().border = '1px solid white';
            //window.status = (xslDiv.getWidth());
            var height = xslDiv.getHeight();
            var width = xslDiv.getWidth();   
            xslDiv.getStyle().position = '';
            win.resizeTo(width + 50, height + 85, true, null, true);
        }
        if (handler) {
            handler();
        }
    }, true);
};

JRapid.prototype.evaluateIfNotNull = function(expr, obj, def) {
	if (expr == null || expr == '0' || !expr) {
		return def;
	}
	var node = application.wrapNode(obj.getContainer().node.parentNode);
	return jrapid.evaluateXpath(expr, node);
};

JRapid.prototype.getRowFor = function(me) {
    var row = me.outerNode;
    while (row && row.getAttribute) {
        if (row.getAttribute('row') == 'row') {
            return row;            
        }
        row = row.parentNode;
    }    
};

JRapid.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();
        }
    }*/            
};

JRapid.prototype.suggestDblClick = function(me, entity, property) {
    this.suggest(me, entity, property);
};

JRapid.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
};

JRapid.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.getChildren().getLength()-1) {
            return;
        }
        if (xsl.outerNode.suggestSelectedIndex >= 0) {
            var oldItem = xsl.getChildren().item(xsl.outerNode.suggestSelectedIndex);
            oldItem.getStyle().backgroundColor = '';
            oldItem.getStyle().color = '';
        }
        
        xsl.outerNode.suggestSelectedIndex++;
        var item = xsl.getChildren().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.getChildren().item(xsl.outerNode.suggestSelectedIndex);
            oldItem.getStyle().backgroundColor = '';
            oldItem.getStyle().color = '';
        }
        
        xsl.outerNode.suggestSelectedIndex--;
        var item =    xsl.getChildren().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);
        }
        
    }
        
};

JRapid.prototype.suggest = function(me, entity, property) {
    var container = me.getContainer();
    var xsl = container.getElementById('suggests');
    xsl.outerNode.suggestSelectedIndex = null;
    xsl.setUrl(jrapid.getServerPath(container) + 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.hasChildren() ? '' : 'none';        
    });
};

JRapid.prototype.multilineRemove = function(me, fpath) {
    var container = me.getContainer();
    var row = jrapid.getRowFor(me);
    var xpath = evaluated(fpath, row);
    var xml = container.getElementById('xml');
    xml.remove(xpath);
    row.parentNode.removeChild(row);
    return;    
};

JRapid.prototype.multilineInsert = function(me, xpath, property) {
    return jrapid.multilineAdd(me, xpath, property, jrapid.getRowFor(me).rowIndex+1);
};

JRapid.prototype.multilineUp = function(me, xpath) {
    var row = jrapid.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);
    }
    
};

JRapid.prototype.multilineDown = function(me, xpath) {
    var row = jrapid.getRowFor(me);    
    if (row.rowIndex < row.parentNode.children.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);
    }    
};

JRapid.prototype.multilineAdd = function(me, fpath, property, rowNum) {
    var tr = jrapid.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.children[tbody.children.length-2].cloneNode(true);               
    tr.style.color = '';                         
    newTr.style.display = '';  
    tr.parentNode.insertBefore(newTr, rowNum ? tbody.children[rowNum] : tbody.children[tbody.children.length-2]); 
    newTr.children[0].style.display = '';
    return true;
};

JRapid.prototype.multilineInsertEntity = function(me, xpath, entity) {
    return jrapid.multilineAddEntity(me, xpath.substring(0, xpath.lastIndexOf('/')), xpath.substring(xpath.lastIndexOf('/')+1, xpath.lastIndexOf('[')), entity, jrapid.getRowFor(me).rowIndex+1);
};

JRapid.prototype.multilineAddEntity = function(me, fpath, property, entity, rowNum, async) {
    var tr = jrapid.getRowFor(me);

    var tbody = tr.parentNode;    
    var container = me.getContainer();    
    var xml = container.getElementById('xml');
    var xmlDoc = xml.getXmlDocument();
    
    // console
    var tx = jrapid.startConsole('Adding', false, 'green');
    
    var httpRequest = HttpRequest.create();
    
	// TODO this should be async but also allow sync to be called later
	httpRequest.open("GET", jrapid.getServerPath(container) + entity + '/0' /*?' + new Date().getTime()*/, false);
    var command = function() {                    
        if (httpRequest.readyState == 4) {
        
        	// end console
        	jrapid.endConsole(tx);
        	
			// check network error
			if (httpRequest.status != 200) {
				jrapid.startConsole('Network error', true, 'red');
				window.status = 'Network error';
				return false;
			}      
			  
            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);
            
            var actualNodesLength = xmlDoc.selectNodes(evaluated(fpath, tbody) + '/' + property).length;
            if (rowNum && rowNum <= actualNodesLength) {
                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);
            
            //create the new TR of the table
			var newTr = tbody.children[tbody.children.length-2].cloneNode(true);            
            tr.style.color = '';                       
            newTr.style.display = '';
            newTr.onkeydown = function() {};        

            tr.parentNode.insertBefore(newTr, rowNum ? tbody.children[rowNum] : tbody.children[tbody.children.length-1].previousSibling);
            
            //display the images if the row is between the last and the first row
            if(rowNum != null){
            	var length = newTr.children.length;
            	for(var i = length - 1; i > 2 ; i--){
					newTr.children[i].style.display = ''; //TD containing the image
            	}
            }
            //jrapid.multilineCalculateIndexes(tbody);
            
            return true;
        }
    };
    try {
	    httpRequest.send("");  
	    return command(); 
	} catch (e) {
		jrapid.startConsole('Network error', true, 'red');
		window.status = 'Network error';				
	}
	return false;
};

JRapid.prototype.multilineCalculateIndexes = function(tbody) {
    for (var i=0; i < tbody.children.length; i++) {
        tbody.children[i].children[0].children[0].value = i;
    }
};

JRapid.prototype.checkIfIsNew = function(me) {

    var node = me.outerNode;
    var success = false;

    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.children.length;
                if (current == (total-3)) {
                    
                    if (node.getAttribute('entity')) {
                        // TODO this is async!
                        success = jrapid.multilineAddEntity(me, node.getAttribute('selectexpr').substring(0, 
                            node.getAttribute('selectexpr').lastIndexOf('/')), node.getAttribute('property'), node.getAttribute('entity'), null, true);
                    } else {
                        success = jrapid.multilineAdd(me, node.getAttribute('selectexpr'), node.getAttribute('property'));
                    }    
                    
                    if (success) {
	                    for (var i=0; i < node.children.length; i++) {
    	                    node.children[i].style.display = '';
        	            }
					}                    
                }
            }
            break;
        }
    }
    
    return success;

};

JRapid.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.children.length;
                return current == (total-3) || current == (total-2);
            }
            break;
        }
    }
    return false;

};


JRapid.prototype.multilineChangedNew = function(me, fpath, property, entity, rowNum) {
//    me.outerNode.onkeydown = function() {};
//    jrapid.multilineAddEntity(me, fpath, property, entity, rowNum);
// alert(1);
};

 
JRapid.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.children.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 = '';
    */
    
    jrapid.suggestEmbeddedEntity(me, application.wrapNode(div), selectexpr, entity, name, null, true);

};

JRapid.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) {
        jrapid.suggestEmbeddedEntity(me, div, xpath, entity, property, handler);
    }
    var style = div.getStyle();
    style.visibility = checked ? 'visible' : 'hidden';
    style.color = checked ? '' : 'green';
}

JRapid.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 = jrapid.startConsole('Embedding', false, 'green');
    
    xml.onreadystatechange = function() {
        if (xml.readyState == 4) {
        	// end console
        	jrapid.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(jrapid.getServerPath(container) + entity + '/0');
}

JRapid.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);
    
};

JRapid.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 = jrapid.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);    
};

JRapid.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);
    }
};



JRapid.prototype.collectionAddEntity = function(me, id, entity, subset, subsetparams, minrows, maxrows, displayCanvas, unique, firstPage) {
    var select = me.getParentNode().getParentNode().getFirstElementChild();

    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 = jrapid.getServerPath(container) + entity + '/' + subset;
        if (subsetparams && subsetparams.length) {
	        var params = subsetparams.split(';');
	        for (var j=0; j < params.length; j++) {
	            url += '/' + jrapid.escapeParam(jrapid.evaluateXpath(evaluated(params[j], me), me));
	        }
	    }
        selectxsl.setUrl(url + (firstPage ? ',page1' : ''));        
    } else {
        selectxsl.setUrl(jrapid.getServerPath(container) + entity + (firstPage ? ',page1' : ''));
    }
    
    selectxsl.setAttribute('baseurl', selectxsl.getUrl());
    
    // console
    var tx = jrapid.startConsole('Add', false, 'green');
    
    selectxsl.refresh(function() {
    	// console
    	jrapid.endConsole(tx);
    	
    	// TODO if (network or service error) return error
    
        var windowSelect = selectxsl.getLastElementChild().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.getPreviousElementSibling().getStyle().display = firstPage ? '' : 'none';
    
    var win = selectxsl.getParentNode();
    win.open();
    win.center();
    
    
    selectxsl.outerNode.slaveSelect = select;
    selectxsl.outerNode.displayCanvas = displayCanvas;
    selectxsl.outerNode.unique = unique;
};

JRapid.prototype.collectionSelectFilter = function(input, value, comboproperty) {
    var xsl = input.getNextElementSibling();
    xsl.setUrl(xsl.getAttribute('baseurl') + (value ? ('!' + comboproperty + '=' + value) : ''));
    xsl.refresh(
    	// TODO if (network or service error) return error
    );
};

JRapid.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;
    }
};
JRapid.prototype.comboKeyDown = function(me, entity, ev) {
    if (ev.getKeyCode() == 13) {
		jrapid.comboOpened = false;
        ev.stopPropagation();
        ev.preventDefault();
    } else if (ev.getKeyCode() == 9) {
        jrapid.comboOpened = false;
        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;
    }
};

JRapid.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.getLastElementChild().getFirstElementChild().getFirstElementChild().outerNode;
        this.comboMove(xsl, tbody, 1);
        jrapid.comboSetValue(me, tbody.children[xsl.outerNode.comboSelectedIndex].title, 
                tbody.children[xsl.outerNode.comboSelectedIndex].getAttribute('rowid'));        
        
    } else if (ev.getKeyCode() == 38 && xsl.getStyle().display != 'none') {
        var tbody = xsl.getLastElementChild().getFirstElementChild().getFirstElementChild().outerNode;    
        this.comboMove(xsl, tbody, -1);
        
        jrapid.comboSetValue(me, tbody.children[xsl.outerNode.comboSelectedIndex].title, 
                tbody.children[xsl.outerNode.comboSelectedIndex].getAttribute('rowid'));    
   
        
    } else if (ev.getKeyCode() != 16) {
        jrapid.comboShow(me, xsl, entity, ev, subset, subsetparams, comboproperty, true);
    }
};

JRapid.prototype.comboMove = function(xsl, tbody, diff) {
    if (xsl.outerNode.comboSelectedIndex == null) {
        xsl.outerNode.comboSelectedIndex = -1;
    }

    if ((diff > 0 && xsl.outerNode.comboSelectedIndex >= tbody.children.length-1) ||
        diff < 0 && xsl.outerNode.comboSelectedIndex <= 0) {
        return;
    }
    
    if (xsl.outerNode.comboSelectedIndex >= 0) {
        var style = tbody.children[xsl.outerNode.comboSelectedIndex].style;
        style.backgroundColor = '';
        style.color = '';
    }

    
    xsl.outerNode.comboSelectedIndex+=diff;
    var style = tbody.children[xsl.outerNode.comboSelectedIndex].style;
    style.backgroundColor = '#000099';
    style.color = '#ffffff';
}

JRapid.prototype.comboSetValue = function(keyInput, key, id) {
    if (key != null) {
        keyInput.setValue(key);
    }
    var input = keyInput.getNextSibling();
    id = id == null ? '' : id;
    if (id != input.getValue()) {
	    input.setValue(id);
	    var newEvent = application.createEvent('HTMLEvents');
	    newEvent.initEvent('change');
	    input.dispatchEvent(newEvent);
	}
    
    keyInput.outerNode.style.backgroundColor = '';
    keyInput.outerNode.style.color = '';    
};

JRapid.prototype.suggestClicked = function(obj, value) {
    var input = application.wrapNode(obj);
    
    input.setValue(value);
    
    var newEvent = application.createEvent('UIEvents');
    newEvent.initUIEvent('change');
    input.dispatchEvent(newEvent);

}

JRapid.prototype.comboShow = function(me, xsl, entity, ev, subset, subsetparams, comboproperty, setFirst) {
    var url;
    var container = me.getContainer();
    if (subset) {
        url = jrapid.getServerPath(container) + entity + '/' + subset;
        if (subsetparams) {
	        var params = subsetparams.split(';');
    	    for (var j=0; j < params.length; j++) {
        	    url += '/' + jrapid.evaluateXpath(evaluated(params[j], me), me);
	        }
	    }
        url += ',page1';
        url += (me.getValue()? ('!' + comboproperty + '=' + me.getValue()) : '');
    } else {
        url = jrapid.getServerPath(container) + entity + ',page1' + (me.getValue()? ('!' + comboproperty + '=' + me.getValue()) : '');
    }

    xsl.setUrl(encodeURI(url));
    xsl.outerNode.comboSelectedIndex = -1;
    xsl.outerNode.comboSelected = me;
	var comboTime = new Date().getTime();
	
	jrapid.comboOpened = true;
	
    xsl.refresh(function() {
    	/* check to see if this is the last call */    	
    	if (!jrapid.comboOpened || (jrapid.lastComboTime && jrapid.lastComboTime > comboTime)) {
    		return;
    	}
		jrapid.lastComboTime = comboTime;
    
    	// 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.getLastElementChild() && xsl.getLastElementChild().getFirstElementChild().getFirstElementChild().hasChildren()) {
            xsl.getStyle().display = '';
            if (setFirst && me.getValue().toLowerCase() == xsl.getLastElementChild().getFirstElementChild().getFirstElementChild().getFirstElementChild().getTitle().toLowerCase()) {
                jrapid.comboSetValue(me, xsl.getLastElementChild().getFirstElementChild().getFirstElementChild().getFirstElementChild().getTitle(), 
                    xsl.getLastElementChild().getFirstElementChild().getFirstElementChild().getFirstElementChild().getAttribute('rowid'));
           }
        } else {
            xsl.getStyle().display = 'none';                
        }
    });    
    jrapid.comboSetValue(me, null, null);    
}
    
JRapid.prototype.comboDblClick = function(me, entity, ev, subset, subsetparams, comboproperty) {
    var container = me.getContainer();
    var xsl = container.getElementById('window_combo_xsl' + me.getId());        
    jrapid.comboShow(me, xsl, entity, ev, subset, subsetparams, comboproperty, false);    
};

JRapid.prototype.comboClicked = function(me, id, key, rowid) {
    var container = me.getContainer();
    var xsl = container.getElementById('window_combo_xsl' + id);        
    xsl.getStyle().display = 'none';    
    jrapid.comboSetValue(xsl.outerNode.comboSelected, key, rowid);    
};

JRapid.prototype.checkboxClicked = function(me, selectexpr, name, value, isEntity, refreshCanvas) {
	var id = me.getValue();    
    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;
    }
};

JRapid.prototype.radioClicked = function(me, selectexpr, name, value, isEntity, refreshCanvas) {
	var id = me.getValue();
    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;
    }
};

JRapid.prototype.fileChange = function(me, entity, width, height) {
    width = width ? width : '';
    height = height ? height : '';
    var win = me.getContainer().getElementById('uploader'); 
    win.open(); 
    win.center(); 
    jrapid.uploadinput = me.outerNode.previousSibling.previousSibling;
    // window.frames['iframe' + entity].location = '../jrapid-runtime/upload.jsp?entity=' + entity + '&width=' + width + '&height=' + height;
    me.getContainer().getElementById('uploader').getFirstElementChild().setSrc('../jrapid-runtime/upload.jsp?entity=' + entity + '&width=' + width + '&height=' + height);
}


function onupload(file) {
    var input = jrapid.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();
}

jrapid.filters = [];

JRapid.prototype.setFilter = function(key, property, value, op) {    
    if (!jrapid.filters[key]) {
        jrapid.filters[key] = new Array();
    }
    if (value == '') {
        jrapid.filters[key][property] = null;
        return;
    }
    if (!op) {
        jrapid.filters[key][property] = [value];
    } else if (op < 0) {
        for (var i=jrapid.filters[key][property].length; i >=0 ; i--) {
            if (jrapid.filters[key][property][i] == value) {
                jrapid.filters[key][property].splice(i,1);                
            }
        }
    } else {
        if (!jrapid.filters[key][property]) {
            jrapid.filters[key][property] = [value];
        } else {
            jrapid.filters[key][property].push(value);
        }
    }
};

JRapid.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);
};

JRapid.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) {
	if (ev.getKeyCode() == 75 && ev.getCtrlKey()) {
		if (com_htmli_ui_Source.cache) {
			com_htmli_ui_Source.cache = false;			
			alert('Cache disabled.');
		} else {
			com_htmli_ui_Source.cache = true;
			alert('Cache enabled.');
		}
	}   
});

/*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();        
    }
});*/


JRapid.prototype.registerPanelLink = function(me, a) {
    var xsl = jrapid.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) {
                        jrapid.openForm(me, 'Application', 'personCanvas', rowid);
                    } else {
                        jrapid.openListing(me, 'Application', 'applicationCanvas', 'forAd', 'forAd/' + rowid, true, function(container) {
                            jrapid.registerPanelLink(application.getElementById('applicationCanvas').getFirstChild(), true, null);
                            
                            //jrapid.openForm(me, 'Person', 'personCanvas', 
                            // function(me, entity, canvas, id) {
                        }, true);
                    }*/
                    application.getElementById('ticketCanvas').setInnerHTML('');
                    jrapid.openForm(me, 'Ticket', 'ticketCanvas', 'forGame/' + rowid, null, 'Sports', true);
                    break;
                }
                obj = obj.getParentNode();
                
                
            }
        }
    );
};

JRapid.prototype.listingTabClick = function(me, entity) {
    var container = me.getContainer();
    var tab = me.getChildren().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.getChildren();
    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';                
        }
    }
};

JRapid.prototype.listingSavedFilterRefresh = function(me) {
/*    this.removeSavedFilters(me);*/
    var t = me.getInnerHTML().split(';');
    var tabpane = me.getContainer().getElementById('tabpane');
    if (!tabpane) {
        return; 
    }
    var tabs = tabpane.getChildren();
    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.getChildren();    
        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);    
    }
};

JRapid.prototype.appendSavedFilter = function(me, title, restriction) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (!tabpane || me.getInnerHTML() == '') {
        return;
    }
    var node = tabpane.getFirstElementChild();
    tabpane.appendTab(node, title);
    tabpane.getLastElementChild().setAttribute('restriction',restriction); 
    var tabs = tabpane.getChildren();
    var id = 'xsl_1_' + tabs.getLength();
    var views = tabpane.getLastElementChild().getChildren();
    for (var i=0; i<views.getLength(); i++) {
        views.item(i).setId('xsl_' + (i+1) + '_' + tabs.getLength());
    }
}


JRapid.prototype.removeSavedFilters = function(me) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (!tabpane || me.getInnerHTML() == '') {
        return;
    }
    var nodes = tabpane.getChildren();
    for (var i=nodes.getLength()-1; i>=0; i--) {
        if (nodes.item(i).getAttribute('restriction')) {
            tabpane.removeTab(i);
        }
    }
}


JRapid.prototype.listingChangeView = function(me) {
    var container = me.getContainer();
    var tabpane = container.getElementById('tabpane');
    if (tabpane) {
        tabpane.getChildren().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();
        }
    }
};                

JRapid.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);        
};


JRapid.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 jrapid.getElementsById(container.getPrefix() + 'thumbnails_' + view + '_' + i);
        case 'icons': 
            return jrapid.getElementsById(container.getPrefix() + 'icons_' + view + '_' + i);
        case 'basic': 
            return jrapid.getElementsById(container.getPrefix() + 'basic_' + view + '_' + i);
    } 
    
    return [];
};


JRapid.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);        
};


JRapid.prototype.page = function(me, page, total) {
    if (page <= total && page > 0) {
        var container = me.getContainer();
        var key = container.getPrefix();
        var xsl = jrapid.listingGetXsl(container);
        var filters = this.getFilters(key);
		var order = xsl.getAttribute('order') ? ('$' + xsl.getAttribute('order')) : '';
        xsl.setUrl(xsl.getAttribute('baseurl') + ',page' + page + (filters.length ? ('!' + filters) : '') + order); 
             
		// console
		var tx = jrapid.startConsole('Paging', false, 'green');
		
        xsl.refresh(function(param, xmlDoc, status) {
        	// console
        	jrapid.endConsole(tx)
        
			// check network error
        	if (status != 200) {
        		jrapid.startConsole('Network error', true, 'green');  
        		return;
        	}
        	
        	// check service error
        	if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        		jrapid.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; 
        	}

        	
        });
    }
};

JRapid.prototype.pageList = function(obj, num, size) {
    var pages = application.wrapNode(obj);
    if (pages.getChildren().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.getFirstElementChild());
    }
};

JRapid.prototype.order = function(me, label, index) {
    var container = me.getContainer();
    var xsl = jrapid.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 = jrapid.startConsole('Ordering', false, 'green');
    
    xsl.refresh(function(i, xmlDoc, status) {
    	// end console
    	jrapid.endConsole(tx);
    	
    	// check network error
		if (status != 200) {
        	jrapid.startConsole('Network error', true, 'green');  
        	return;
       	}
        	
        // check service error
        if (xmlDoc == null || xmlDoc.documentElement == null || xmlDoc.documentElement.tagName == 'exception') {
        	jrapid.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);
};


JRapid.prototype.filter = function(property, value, me, op) {    
    var container = me.getContainer();
    this.setFilter(container.getPrefix(), property, value, op);
    this.refreshFilter(container);
};

JRapid.prototype.refreshFilter = function(container) {    
    var xsl = jrapid.listingGetXsl(container);
    var filters = this.getFilters(container.getPrefix());
    if (xsl.getAttribute('useparams')) {
        xsl.setUrl(xsl.getAttribute('baseurl') + '/' + container.node.subsetParams + ',page1' + (filters.length ? ('!' + filters) : ''));
    } else {
	    xsl.setUrl(xsl.getAttribute('baseurl') + ',page1' + (filters.length ? ('!' + filters) : ''));
	}
    
    // start console
    var tx = jrapid.startConsole('Filtering', false, 'green');
    
    xsl.refresh(function() {
		// end console
		jrapid.endConsole(tx);
		
		// TODO if (network or service error) return error
    });
};

JRapid.prototype.getScreenX = function(obj) {
	if (obj.getBoundingClientRect) {
		return obj.getBoundingClientRect().left;
	} else {
		// TODO firefox
		return 0;
	}
};

JRapid.prototype.getScreenY = function(obj) {
	if (obj.getBoundingClientRect) {
		return obj.getBoundingClientRect().top;
	} else {
		// TODO firefox
		return 0;
	}
};

JRapid.prototype.tooltipOn = function(me) {
    var tooltip = me.getAttribute('tooltip');
    var div = me.getContainer().getElementById('tooltip');
    div.getLastElementChild().setInnerHTML(tooltip);    
    var style = div.getStyle();
    
   
    var top = 0;
    var left = 0;
    var screenX = jrapid.getScreenX(me.outerNode);
    var screenY = jrapid.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.getFirstElementChild().getStyle();
    style.height = div.getLastElementChild().getHeight() + 'px';
    style.width = div.getLastElementChild().getWidth() + 'px';

};

JRapid.prototype.tooltipOff = function(me) {
    var div = me.getContainer().getElementById('tooltip');
    div.getStyle().display = 'none';
};

JRapid.prototype.javascriptFormAction = function(me, name) {
    var container = me.getContainer();
    var id = container.getElementById('xml').getXmlDocument().selectSingleNode('/*').getAttribute('id');
    var ids = [id];
    eval(name + '(me, ids)');
    return false;
}

JRapid.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;
}

JRapid.prototype.getIdsAsString = function(me) {
    var ids = jrapid.getIds(me);
    var s = '';
    for (var i=0; i < ids.length; i++) {
        s += (i > 0 ? ',' : '') + ids[i];
    }
    return s.length ? s : '0';
}

JRapid.prototype.getIds = function(me) {
    var container = me.getContainer();

    var type = container.getElementById('selectview').getValue();
    var table = jrapid.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.getLastElementChild().getChildren().item(selected[i]).getAttribute('rowid');
        }
    } else {
        var items = jrapid.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;
}

JRapid.prototype.listingMouseOverThumbnail = function(me) {
    me.getFirstElementChild().getFirstElementChild().getFirstElementChild().getFirstElementChild().getNextSibling().getStyle().display = 'inline';
};

JRapid.prototype.listingMouseOutThumbnail = function(me) {
    me.getFirstElementChild().getFirstElementChild().getFirstElementChild().getFirstElementChild().getNextSibling().getStyle().display = 'none';
};

JRapid.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');        
    }
}

JRapid.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');        
    }
}

JRapid.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');        
    }    
};

JRapid.prototype.listingClicked = function(me, id) {
    var node = me.getContainer().node;
    try {
	    if (node.triggers && node.triggers.length) {
	    	for (var i=0; i < node.triggers.length; i++) {
	    		node.triggers[i](me, id);
	    	}
	    }	
	} catch (e) {}
};

JRapid.prototype.registerPanelListing = function(me, entity, subset, subsetparams, canvas) {
	var container = me.getContainer();

	var params = subsetparams.split(';');
	for (var i=0; i < params.length; i++) {
		var childContainer = container.getElementById(params[i]).getChildContainer();
		var node = childContainer.node;
		if (node.triggers == null) {
			node.triggers = [];
		}
		node.triggers[node.triggers.length] = function(foo, id) {
			// TODO only xsl (and just the current xsl) should be refreshed
			// TODO it must work with more than one subsetparam
			// TODO it must use the canvas passed by parameter, instead of me.getParentNode()
			
			var child = me.getChildContainer();
			child.node.subsetParams = id;
			jrapid.loadListing(child, entity, subset + '/' + id, false, me.getParentNode());				
		};
	}	
};

JRapid.prototype.registerPanelForm = function(me, entity, defaultsetparams) {
	var container = me.getContainer();

	var params = defaultsetparams.split(';');
	for (var i=0; i < params.length; i++) {
		var childContainer = container.getElementById(params[i]).getChildContainer();
		var node = childContainer.node;
		if (node.triggers == null) {
			node.triggers = [];
		}
		node.triggers[node.triggers.length] = function(foo, id) {
			// TODO only xsl (and just the current xsl) should be refreshed
			// TODO it must work with more than one param and with defaultset
			jrapid.loadForm(me.getChildContainer(), entity, id, null, false, false, false, false, true);			
		};
	}	
};



JRapid.prototype.showSaveFilter = function(me) {
    var container = me.getContainer();
    
    container.getElementById('saveFilterPanel').getStyle().display='';
    container.getElementById('saveFilterLink').getStyle().display='none';        
    container.getElementById('saveFilterInput').focus();
}
JRapid.prototype.saveFilter = function(me) {
    var container = me.getContainer();
    container.getElementById('saveFilterPanel').getStyle().display='none';    
    container.getElementById('saveFilterLink').getStyle().display='';
    
    var xsl = jrapid.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
        );
    });    
}

JRapid.prototype.listingRemove = function(me, name) {
    if (confirm('Sure to delete these elements?')) {
        var ids = this.getIds(me);
                        
        var container = me.getContainer();    
        container.getElementById('xmlrpcserver').executeAsync(name + '.remove', function(id, e) {
            if (e) {
                alert('Unable to delete');
            } else {
                jrapid.refreshFilter(container);
            }
        }, ids);
        
    }
    return false;
    
    
}

JRapid.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];        
        }
    }
    
	var hash = window.location.hash;
	if (hash && hash.length > 0) {
		var params = hash.substring(1).split('&');
	    for (var i=0; i < params.length; i++) {
	        var parameter = params[i].split("=");	        
	        if (parameter[0] == param) {
	        	return parameter[1];        
	        }
	    }
	}
	
    return def;
};

JRapid.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");
    }
    
};


JRapid.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;
        }
    }

}

JRapid.prototype.isEscapedChar = function(escapedchars, char){
    for(var i=0; i < escapedchars.length; i++){
        if(char == escapedchars[i]){
            return true;
        }
    }
    return false;
}

JRapid.prototype.setMask = function(me) {
    if (!me.getValue()) {
        me.setValue(me.getAttribute('mask'));
    }
}

JRapid.prototype.selectTimeSync = function(me) {
	var children = me.getParentNode().getChildren();
	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();
};

JRapid.prototype.selectDateSync = function(me) {
	var children = me.getParentNode().getChildren();
	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.value + '/' + s2.value + '/' + s3.value);
	input.sync();
};


JRapid.prototype.auditHistory = function(me, entity) {
	var id = me.getContainer().getElementById('xml').getXmlDocument().selectSingleNode('/*/@id').nodeValue;
	window.open('../jrapid-runtime/history.jsp?entity=' + entity + '&id=' + id, entity, 'resizable=yes,status=no,scrollbars=yes,width=500,height=300');
};

JRapid.prototype.navigate = function(me, select, dir, entity) {
	var options = select.outerNode.options;
	var newIndex = select.outerNode.selectedIndex + dir;
	if (newIndex >= 0 && newIndex < options.length) {
		options[newIndex].selected = true;
	}
	jrapid.loadForm(me.getContainer(), entity, select.outerNode.value);
};


JRapid.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;
    };
    */
    
    
    
    
JRapid.prototype.panelResizeTable = function (table, height) {
	
	for (var i=0; i < table.children[0].children.length; i++) {
		jrapid.panelResizeTr(table.children[0].children[i], height);
	}
};		
		
JRapid.prototype.panelResizeTr = function(tr, height) {
	var fixedHeight = 0;
	for (var i=0; i < tr.children.length; i++) {
		if (tr.children[i].getAttribute('panelheight') && tr.children[i].getAttribute('panelheight').indexOf('%') == -1) {
			fixedHeight += parseInt(tr.children[i].getAttribute('panelheight'));
		}
	}
			
	for (var i=0; i < tr.children.length; i++) {
		jrapid.panelResizeTd(tr.children[i], height-fixedHeight);
	}
};
		
JRapid.prototype.panelResizeTd = function(td, height) {

        if (td.getAttribute('panelheight')) {
                var tdHeight = td.getAttribute('panelheight');
                var index = tdHeight.indexOf('%');
                var actualHeight = index == -1 ? parseInt(tdHeight) : parseInt(tdHeight)*height/100;
                td.children[0].style.height = actualHeight + 'px';
                /*td.children[0].style.overflow = 'hidden';*/
                var fixedHeight = 0;
                for (var i=0; i < td.children[0].children.length; i++) {
                        if (td.children[0].children[i].getAttribute('panelheight') && td.children[0].children[i].getAttribute('panelheight').indexOf('%') == -1) {
                                fixedHeight += parseInt(td.children[0].children[i].getAttribute('panelheight'));
                        }
                }
                for (var i=0; i < td.children[0].children.length; i++) {
                        var node = td.children[0].children[i];
                        if (node.getAttribute('htmliclass') == 'com_htmli_ui_Accordeon') {
                                jrapid.panelResizeAccordeon(node, actualHeight-fixedHeight);
                        } else {
                                jrapid.panelResizeItem(node, actualHeight-fixedHeight);
                        }
                }
        }
};

		
JRapid.prototype.panelResizeItem = function(item, height) {
	if (item.getAttribute('panelheight')) {
		if (item.getAttribute('panelheight').indexOf('%') == -1) {
			item.style.height = item.getAttribute('panelheight');
		} else {
			item.style.height = (height*parseInt(item.getAttribute('panelheight'))/100) + 'px';
		}
		item.style.overflowY = 'auto';
	}
	
	if (item.getAttribute('listing')) {
		jrapid.resizeTable(jrapid.listingGetXsl(application.wrapNode(item.children[0]).getChildContainer()));
	}			
};
		
JRapid.prototype.panelResizeAccordeonItem = function(item, height) {
	var fixedHeight = 0;
	var children = item.getChildNodes();
	for (var i=0; i < children.getLength(); i++) {
		if (children.item(i).getAttribute('panelheight') && children.item(i).getAttribute('panelheight').indexOf('%') == -1) {
			fixedHeight += parseInt(children.item(i).getAttribute('panelheight'));
		}
	}
	for (var i=0; i < children.getLength(); i++) {
		var node = children.item(i);
		jrapid.panelResizeItem(node.outerNode, height-fixedHeight);				
	}
}
		
JRapid.prototype.panelResizeAccordeon = function(node, height) {
	var accordeon = application.wrapNode(node);
	var children = accordeon.getChildNodes();
	for (var i=0; i < children.getLength(); i++) {
		var n = children.item(i);
		jrapid.panelResizeAccordeonItem(n, height - 21*children.getLength());				
	}
}
       
       
JRapid.prototype.moreMouseOut = function(me, ev) {
    var evt = window.event;
    if (!evt) {
        return true;
    }
    var el;
    if (evt.type == "mouseout") {
   		el = evt.toElement;
    } 
    if (!el) {
        return false;
    }
    while (el) {
        if (el == evt.srcElement || (el.id && el.id.indexOf('tooltip') > 0)) {
        	return false;
        }
        el = el.parentNode;
    }
    me.outerNode.lastChild.style.display = 'none';	    
    return true;
}
  
JRapid.prototype.openReports = function(me, report, ids) {
    for (var j=0; j < ids.length; j++) {
        jrapid.openReport(me, report, ids[j]);
    }
};  

JRapid.prototype.openReport = function(me, report, id) {
	window.open('../report/' + report + '?id=' + id + '&pdf', '_blank', 'width=700,height=600,resizable=yes');
};