Hsa.form = {

  _setFcnv: function(inputElem, pNode) {
	if (pNode && pNode.firstChild)
		inputElem.value = pNode.firstChild.nodeValue;
  },

  _fcnv: function(pNode) {
	if (pNode && pNode.firstChild) {
		return pNode.firstChild.nodeValue;
	} else {
		return '';
	}
  },
  
	_checkedRadios: {},
	_lastPressedSubmitButton: null,

	// Because IE is unable to uncheck the other checked radio button with the same input name we have to keep track of it and do it manually in JS.
	// IE is also unable to show the radio button as checked so that has to be done in JavaScript. In Mozilla etc. this works
	// without this hack, but it does no harm either.
	_radioChecked: function (inputRadioObj) {
			var inputName = inputRadioObj.name;
			if (Hsa.form._checkedRadios[inputName]) {
				var wasChecked = document.getElementById(Hsa.form._checkedRadios[inputName]);
				if (wasChecked) { 
				   wasChecked.checked = ''; 
				}
			}
			Hsa.form._checkedRadios[inputName] = inputRadioObj.id;
			inputRadioObj.checked = 'checked';
	},

	_addressRadioSelected: function (event) {
	        var target = window.event ? window.event.srcElement : e ? e.target : null;
		var radiobuttonNode = target;
		var tdNode = radiobuttonNode.parentNode;
		var tbodyNode = tdNode.parentNode.parentNode;
		for (var i=0; i<=tbodyNode.childNodes.length-1; i++) {
			var trNode = tbodyNode.childNodes[i];
			for (var j=0; j<=trNode.childNodes.length-1; j++) {
				var curTdNode = trNode.childNodes[j];

				if (curTdNode.className = 'address first active') {
					curTdNode.className = 'address first';
				} else {
					curTdNode.className = 'address';
				}
			}
		}
		if (tdNode.className = 'address first')
			tdNode.className = 'address first active';
		else
			tdNode.className = 'address';
	},

_printSpacerImage: function(parentElem, width) {
    var im = document.createElement('IMG');
    im.src = '/img/spacer.gif';
    im.setAttribute('width', width ? width : 14);
    im.setAttribute('height', '1');
    parentElem.appendChild(im);
},

			_xmlTree2Html: function (parentElem, xmlElement, currentDepth) {
				var childNodes = xmlElement.childNodes;
				if (childNodes && childNodes.length>0) {
					for (var i=0; i <= childNodes.length-1; i++) {
						var curChild = xmlElement.childNodes[i];
						// 1=element, 3=text
                        if ( curChild.nodeType == 1 ) {
							var newNode = document.createElement(curChild.nodeName);
							var attributes = curChild.attributes;
							for (var j=0; j <= attributes.length-1; j++) {
								if (attributes[j].nodeName == 'class')
									newNode.className = attributes[j].nodeValue;
								else
									newNode.setAttribute(attributes[j].nodeName, attributes[j].nodeValue);
							}
							parentElem.appendChild(newNode);
							this._xmlTree2Html(parentElem.lastChild, curChild, currentDepth+1);
						} else if (curChild.nodeType == 3) {
							parentElem.appendChild(document.createTextNode(curChild.nodeValue));
						} 
					}
				}
			},



  initForm: function(containerObjectId, methodName, initQs, originalPageQs) {
	var containerObject = document.getElementById(containerObjectId);
	if (containerObject.nodeName != 'DIV') {
		alert('container must be a DIV.');
		return;
	}
	var formObj = document.createElement('FORM');
	formObj.id = 'mainForm';
	formObj._hsa_initQs = initQs;
	formObj._hsa_originalPageQs = originalPageQs;
	formObj._hsa_originalPageQsIntoQs = originalPageQs;
	formObj.ajaxApiMethodName = methodName;
	formObj.action = 'javascript: Hsa.form.submitFormId(\'' + formObj.id + '\');';
	containerObject.appendChild(formObj);
	this.submitForm(formObj);
  },


  initAjaxContent: function(containerObjectId, methodName) {
	var containerObject = document.getElementById(containerObjectId);
	if (containerObject.nodeName != 'DIV') {
		alert('container must be a DIV.');
		return;
	}
	jQuery.ajax(this._ajaxRequestOptionsJ(Hsa.config.backendpath + methodName + '.xml', 'id=' + escape(containerObjectId)));
  },


  helpBubbleContent: function(containerObjectId, methodName) {
	var containerObject = document.getElementById(containerObjectId);
	if (containerObject.nodeName != 'DIV') {
		alert('container must be a DIV.');
		return;
	}
	jQuery(containerObject).load(Hsa.config.helpbubblebackendpath + methodName + '.xml');
  },

  submitForm: function(formObj) {
	if (formObj.hsaFormSubmitted)
		return;
	else
		formObj.hsaFormSubmitted = true;

	var queryString;
	if (formObj._hsa_initQs) {
		queryString = formObj._hsa_initQs;
		formObj._hsa_initQs = null;
	} else {
		queryString = jQuery(formObj).serialize();
	}
	if (formObj._hsa_originalPageQsIntoQs) {
		if (queryString.length != 0)
			queryString += '&';
		queryString += formObj._hsa_originalPageQsIntoQs;
		formObj._hsa_originalPageQsIntoQs = null;
	}
	if (formObj._hsa_originalPageQs) {
		if (queryString.length != 0)
			queryString += '&';
		queryString += 'originalPageQs=' + escape(formObj._hsa_originalPageQs);
	}


	var methodName = formObj.ajaxApiMethodName;
	jQuery.ajax(this._ajaxRequestOptionsJ(Hsa.config.backendpath + methodName + '.xml', queryString));
  },

  submitFormB: function(formObj, button) {
		if (!button.hsaClicked) {
			button.hsaClicked = true;
			Hsa.form._lastPressedSubmitButton = button;
			this.submitForm(formObj);
		}
  },

  submitFormId: function(id) {
	var formObj = document.getElementById(id);
	this.submitForm(formObj);
  },

  setPhase: function (formid, phase) {
	var formObj = document.getElementById(formid);
	this.setPhaseObj(formObj, phase);
   },

   setPhaseObj: function (formObj, phase) {
	var inputes = formObj.getElementsByTagName('input');
	for (var a=0; a<=inputes.length-1; a++) {
		if (inputes[a].name == 'phase') {
			inputes[a].value = phase;
			return;
		}
	}
   },

   getPhaseObj: function (formObj) {
	var inputes = formObj.getElementsByTagName('input');
	for (var a=0; a<=inputes.length-1; a++) {
		if (inputes[a].name == 'phase')
			return inputes[a].value;
	}
   },

  	_ajaxRequestOptionsJ : function (url, queryString) {
	        return {beforeSend:	Hsa.requestStart,
			cache:		false,
			data:		queryString,
			dataType:	'xml',
			error:		Hsa.requestEnd,
			success:	Hsa.form._ajaxResponseHandler,
			type:		'POST',
			url:		url
		};
	},

	_ajaxCreatorHandler : function (request) {
		Hsa.requestStart();
	},

	_ajaxResponseHandler : function (responseData, textStatus) {
        
        var response = responseData.getElementsByTagName("ajax-response");
		if (response == null || response.length != 1) {
			Hsa.requestEnd();
			return;
		}
	       	Hsa.form._processAjaxResponse( response[0].childNodes );
		Hsa.requestEnd();
	},

    _processAjaxResponse: function( xmlResponseElements ) {
        for (var i=0 ; i<=xmlResponseElements.length-1 ; i++ ) {
            var responseElement = xmlResponseElements[i];
            
            if ( responseElement.nodeType != 1 )
                continue;
            
            var responseType = responseElement.getAttribute("type");
            var responseId   = responseElement.getAttribute("id");
            
            if ( responseType == "object" ) {
                this._processAjaxObjectUpdate( responseId, responseElement );
            } else if ( responseType == "content" ) {
                this._processAjaxContentResponse( responseId, responseElement );
            } else if ( responseType == "element" ) {
                var realElement = document.getElementById(responseId);
            
                if (!realElement)
                    alert('error: no element with the id "' + responseId + '" exists!');
            
                var content = responseElement.childNodes[0].data;
                realElement.innerHTML = content;
            } else if ( responseType == "form" ) {
                this._spawnForm(null, responseElement, 0, null, null);
            } else if ( responseType == 'redir') {
                var loc = responseElement.getElementsByTagName('location')[0];
            
                if (loc.getAttribute('url')) {
                    if (loc.getAttribute('window')) {
                        if (loc.getAttribute('window') == 'top') {
                            window.top.location = loc.getAttribute('url');
                        } else { // add more options here if needed
                            window.location = loc.getAttribute('url');
                        }
                    } else {
                        window.location = loc.getAttribute('url');
                    }
                } else {
                    var methodName = loc.getAttribute('method');
                    var queryString = loc.getAttribute('queryString');
                    jQuery.ajax(this._ajaxRequestOptionsJ(Hsa.config.backendpath + methodName + '.xml', queryString));
                }
            } else if ( responseType == 'control') {
                this._processAjaxControl( responseId, responseElement);
            } else if ( responseType == "productSelector" ) {
                Hsa.form._current_hsa_productSelector._processProductSelectorResponse(responseElement);
            } else if ( responseType == "productSelector_orderInfo" ) { // TODO: Vaihda nimeksi pelkka orderInfo
                this._processOrderInfoResponse(responseElement);
            } else if ( responseType == 'productSelector_included') {
                Hsa.form._current_hsa_productSelector._processIncludedResponse(responseElement);
            } else if ( responseType == 'productSelector_products') {
            	Hsa.form._current_hsa_productSelector._processProductResponse(responseElement);
            } else if ( responseType == 'paymentForm') {
                this._spawnPaymentForm(responseElement);
            } else if ( responseType == 'calendar') {
                var thatCal = document.getElementById(responseId);
                thatCal.hsa_HsaCalendarObject._processHsaCalendarData(null, responseElement, 0);
            } else if ( responseType == 'controlReady') {
                this._processControlReadyResponse(responseId, responseElement);
            } else {
                alert('unrecognized Ajax response type: ' + responseType );
            }
        }
    },

	_processAjaxControl: function (ajaxObjectId, xmlElem) {
		var childNodes = xmlElem.childNodes;
		if (childNodes && childNodes.length>0) {
			for (var i=0; i <= childNodes.length-1; i++) {
				var curChild = xmlElem.childNodes[i];
				if (curChild.nodeName == 'do') {
					var action = curChild.getAttribute('action');
					var ao = document.getElementById(ajaxObjectId);
					jQuery('#columnsContainer').removeClass('paymentProcess');
					if (action == 'show') {
						if (ajaxObjectId == 'subscriptionInfo2')
							jQuery('#columnsContainer').addClass('paymentProcess');
							//document.getElementById('columnsContainer').className = 'fC paymentProcess';
						if (ao)
							ao.style.display = 'block';
					} else if (action == 'hide') {
						if (ao)
							ao.style.display = 'none';
						if (ajaxObjectId == 'subscriptionInfo2')
    						jQuery('#columnsContainer').addClass('fC');
							//document.getElementById('columnsContainer').className = 'fC';
					} else if (action == 'del') {
						if (ao)
							ao.parentNode.removeChild(ao);
					} else if (action == 'submit') {
						if (ao)
							ao.submit();
					} else if (action == 'refreshHeaderLogin') {
						jQuery.ajax(this._ajaxRequestOptionsJ(Hsa.config.backendpath + 'util_kirjautuneena.xml', 'id=headerLoginContainer'));
						
					  //TABS
					} else if (action == 'initTabs') {
					  var activeTabNumber = curChild.getAttribute('activeTabNumber');
					  if (!activeTabNumber) activeTabNumber = 1;
					  Hsa.tabs.init(activeTabNumber);
					} else if (action == 'removeTabs') {
					  jQuery('#mainFormDiv').append(ao);
					  jQuery('#tabs-wrapper').remove();
					  jQuery('#mainForm').empty(); //empty mainform to get rid of flash of form without tabs
					}
				} else if (ajaxObjectId == 'processIndicator') {
				    if (curChild.nodeName == 'set-phase') {
				        var phase = parseInt(curChild.getAttribute('phase')) - 1;
                        if (phase == 3) {
                            jQuery('#orderIndicator li').each(function(i) {
                                if (i == phase) {
                                    jQuery(this).removeClass('inactive');
                                    jQuery(this).addClass('active');
                                } else {
                                    jQuery(this).removeClass('active');
                                    jQuery(this).addClass('inactive');
                                    jQuery(this).find('a').attr('href','javascript:;');
                                }
                            });
                        } else {
                            jQuery('#orderIndicator li').each(function(i) {
                                if (i == phase) {
                                    jQuery(this).removeClass('inactive');
                                    jQuery(this).addClass('active');
                                    jQuery(this).find('a').attr('href','javascript:;');
                                } else if (i > phase) {
                                    jQuery(this).removeClass('active');
                                    jQuery(this).addClass('inactive');
                                    jQuery(this).find('a').attr('href','javascript:;');
                                } else {
                                    jQuery(this).removeClass('inactive');
                                    jQuery(this).removeClass('active');
                                    jQuery(this).find('a').attr('href','javascript:Hsa.orderIndicator.openPreviousPhase('+ (i + 1) + ');');
                                }
                            });
                        }

                        // The indicator remains hidden until a phase is explicitly given in tilaus-tee.xml
    				    jQuery('#orderIndicator').show();
    				    
				    } else if (curChild.nodeName == 'override-text') {
				        var phase = parseInt(curChild.getAttribute('phase'));
				        if (phase > 0 && curChild.firstChild.nodeValue != null) {
       				        jQuery('#orderIndicator li.order-' + (phase - 1) + ' a').html(curChild.firstChild.nodeValue)
       				    }
				    }
                }
			}
		}
	},

        _processAjaxObjectUpdate: function( ajaxObjectId, responseElement ) {
        },

	_processControlReadyResponse: function (responseId, xmlElem) {
	        var xmlNodes = xmlElem.childNodes;
	        for (var i=0 ; i<=xmlNodes.length-1 ; i++ ) {
			var xmlNode = xmlNodes[i];
			if ( xmlNode.nodeType != 1 )
              			continue;
			var ele = document.getElementById(xmlNode.getAttribute('id'));
			if (ele)
				ele.hsaReady = xmlNode.firstChild.nodeValue;
		}
	},

	_processAjaxContentResponse: function( responseId, xmlElem ) {
        var xmlNodes = xmlElem.childNodes;
        
        for (var i=0 ; i<=xmlNodes.length-1 ; i++ ) {
            var xmlNode = xmlNodes[i];
            
            if ( xmlNode.nodeType != 1 )
                continue;
            var contentId = xmlNode.getAttribute("id");
            var ele = document.getElementById(contentId);
            if (ele) {
                while( ele.hasChildNodes() ) { ele.removeChild( ele.lastChild ); }
                this._xmlTree2Html(ele, xmlNode, 0);
                // plaintext only: ele.appendChild(document.createTextNode(Hsa.form._fcnv(xmlNode)));
            }
		}
	},

	_processOrderInfoResponse: function (xmlElem) {
        var xmlNodes = xmlElem.childNodes;
        var infoResponseTo = xmlElem.getAttribute('id');
        
        if (!infoResponseTo)
            return;
        
        for (var i=0 ; i<=xmlNodes.length-1 ; i++ ) {
            var xmlNode = xmlNodes[i];
            if (xmlNode.nodeName == 'do') {
                if (xmlNode.getAttribute('action') == 'hide') {
                    jQuery('#subscriptionInfo').hide();
                    jQuery('.productSelector #mainFormDiv').removeClass('narrow');
                    if (Hsa.form._lastPressedSubmitButton) Hsa.form._lastPressedSubmitButton.hsaClicked = false;
                } else if (xmlNode.getAttribute('action') == 'show') {
                    jQuery('#subscriptionInfo').show();
                    jQuery('.productSelector #mainFormDiv').addClass('narrow');
                }
            } else if (xmlNode.nodeName == 'price') {
                jQuery('#subscriptionPrice .price').html(xmlNode.getAttribute('total') + ' €');
                jQuery('#subscriptionPrice .monthly').html('(' + xmlNode.getAttribute('monthly') + '€/kk)');
            } else if (xmlNode.nodeName == 'benefits') {
                if (xmlNode.firstChild) {
	                jQuery('#subscriptionPrice p').html(xmlNode.firstChild.nodeValue);
	            } else {
	            	jQuery('#subscriptionPrice p').html('');
	            }
            } else if (xmlNode.nodeName == 'text') {
                var parentElem = document.getElementById(infoResponseTo);
                if (parentElem) {
                    while( parentElem.hasChildNodes() ) { parentElem.removeChild( parentElem.lastChild ); }
                    Hsa.form._xmlTree2Html(parentElem, xmlNode, 0);
                }
            } else if (xmlNode.nodeName == 'xhtml') {
				var content = xmlNode.childNodes[0].data;
				jQuery('#subscriptionPrice .free-text').html(content);
            } else if (xmlNode.nodeName == 'continueButton' || xmlNode.nodeName == 'backButton') {
                var parentElem = document.getElementById(infoResponseTo + '_' + xmlNode.nodeName);
                if (parentElem) {
                    if (xmlNode.getAttribute('state') == 'hidden') {
                        jQuery(parentElem).addClass('buttonDisabled');
                        parentElem.setAttribute('onclick','return(false)');
                    } else if (xmlNode.getAttribute('state') == 'unchecked') {
                        parentElem.hsaClicked = false;
                        jQuery(parentElem).removeClass('buttonDisabled');
                        parentElem.removeAttribute('onclick');
                        parentElem.style.display = 'block';
                    }
                }
            }
        }
	},

	_spawnPaymentForm: function (xmlElem) {
		parentElem = document.getElementById(xmlElem.getAttribute('id'));
		if (!parentElem && xmlElem.getAttribute('siblingTo')) {
			var appendSiblingTo = document.getElementById(xmlElem.getAttribute('siblingTo')).parentNode;
			var divObj = document.createElement('DIV');
			divObj.id = xmlElem.getAttribute('id');
			appendSiblingTo.appendChild(divObj);
			parentElem = divObj;
		}

		if (!parentElem) {
			alert('paymentForm parent ' + xmlElem.getAttribute('id') + ' is missing!');
			return;
		}

		while( parentElem.hasChildNodes() ) { parentElem.removeChild( parentElem.lastChild ); }

		for (var i=0; i <= xmlElem.childNodes.length-1; i++) {
			var curChild = xmlElem.childNodes[i];
			if (curChild.nodeName == 'formdata')
				Hsa.form._xmlTree2Html(parentElem, curChild, 100);
		}
	},

	_spawnForm: function (parentElem, xmlElem, currentDepth, parentType, formObject) {
	
	//console.log("spawnform");
        
        
		if (xmlElem.nodeName == 'response') {

			parentElem = document.getElementById(xmlElem.getAttribute('id'));
			if (!parentElem && xmlElem.getAttribute('siblingTo')) {
				var appendSiblingTo = document.getElementById(xmlElem.getAttribute('siblingTo')).parentNode;
			
			      //TABS
			      //if mainForm is wrapped in tab, then look one step up for correct parent
			      if( jQuery(appendSiblingTo).hasClass('tab-content') ){
				    appendSiblingTo = appendSiblingTo.parentNode;
			      }
				
				var formObj = document.createElement('FORM');
				formObj.id = xmlElem.getAttribute('id');
				appendSiblingTo.appendChild(formObj);
				parentElem = formObj;
			}
			formObject = parentElem;

			if (!parentElem) {
				alert('Form parent ' + xmlElem.getAttribute('id') + ' is missing!');
				return;
			}
			parentElem.hsaFormSubmitted = false;
			parentElem.ajaxApiMethodName = xmlElem.getAttribute('action');
			
			parentElem.action = 'javascript: Hsa.form.submitFormId(\'' + parentElem.id + '\');';
			while( parentElem.hasChildNodes() ) { parentElem.removeChild( parentElem.lastChild ); }

			if (!xmlElem.getAttribute('siblingTo')) {
				var cpyP = Hsa.currentPageYPosition();
				var contentP = Hsa.findPos(document.getElementById('content'));
				if (cpyP > contentP[1])
					window.scroll(0,0);
			}
			
			//TABS
			
			// possible to move the mainFormDiv inside specified element (as last element)
			var placementElemId = xmlElem.getAttribute('placement');
			if(placementElemId){
			    var placementElem = document.getElementById(placementElemId);
			    jQuery('#mainFormDiv').appendTo(placementElem);
			}
	    
			var tabId = xmlElem.getAttribute('tabId');
			if(tabId){
			    //console.log(parentElem);
			    //console.log(tabId);
			    var tabsWrapperElem = document.getElementById('tabs-wrapper');
			    if(!tabsWrapperElem){
				//console.log("luodaan wrapperi");
				jQuery(parentElem).wrap('<div id="tabs-wrapper" />');
				jQuery(parentElem).before('<ul class="tabs fC"></ul>');
				// <li><a href="#tab-asiakasnumerolla">Asiakasnumerolla</a></li><li><a href="#tab-apua-kirjautumiseen">Apua kirjautumiseen</a></li>
			    }
				
			    var tabElem = document.getElementById(tabId);
			    if(!tabElem){
				  //if form with same id already exists (from previous view) and is not inside tabs-wrapper, make sure it will end up inside it
				  if( jQuery(parentElem).parent().attr('id') != 'tabs-wrapper' ){
					jQuery(parentElem).appendTo('#tabs-wrapper');
				  }
				  
				  jQuery(parentElem).wrap('<div id="'+tabId+'" class="tab-content" />');
				  var tabLabel = xmlElem.getAttribute('tabLabel');
				  jQuery('#tabs-wrapper ul.tabs').append('<li><a href="#' + tabId + '">' + tabLabel + '</a></li>');
			    } else {
				  jQuery(parentElem).appendTo(tabElem);
			    }
			}
			
			
		} else if (xmlElem.nodeName == 'insideresponse') {
		}

		if (xmlElem.nodeName == 'fieldset' || xmlElem.nodeName == 'textset') {
			// legend on fieldsetin sisalla, lookahead.
			if (xmlElem.getElementsByTagName('legend').length > 0) {
				var xmlLegendElem = xmlElem.getElementsByTagName('legend')[0];
				var legendElem = document.createElement('H' + (1+currentDepth));
				legendElem.className='em';
				if (xmlLegendElem.getAttribute('id')) {
				    legendElem.id = xmlLegendElem.getAttribute('id');
				}
				if (xmlLegendElem.getAttribute('altContent')) {
				    legendElem.altContent = xmlLegendElem.getAttribute('altContent');
				    legendElem.origContent = Hsa.form._fcnv(xmlLegendElem)
				}

                //console.log(xmlElem.getAttribute('type'), xmlElem.getAttribute('hiddenByDefault'), (xmlElem.getAttribute('hiddenByDefault') == '1'))
				if (xmlElem.getAttribute('hiddenByDefault') == '1') {
				    legendElem.className += ' hiddenByDefault';
				}
				legendElem.appendChild(document.createElement('EM'));
				if (xmlLegendElem.getAttribute('help')) {
					var helpId = xmlLegendElem.getAttribute('help');

					legendElem.lastChild.appendChild(document.createElement('SPAN'));
					legendElem.lastChild.lastChild.className='helpWrapper';

					legendElem.lastChild.lastChild.appendChild(document.createElement('A'));
					legendElem.lastChild.lastChild.lastChild.className = 'helpButton';
					legendElem.lastChild.lastChild.lastChild.href='javascript:Hsa.form.helpBubbleContent(\'HsaHelpBubble_' + helpId + '\', \'' + helpId + '\');';
					legendElem.lastChild.lastChild.lastChild.appendChild(document.createElement('IMG'));
					legendElem.lastChild.lastChild.lastChild.lastChild.src='/img/button_title_help.gif';

					legendElem.lastChild.lastChild.appendChild(document.createElement('DIV'));
					legendElem.lastChild.lastChild.lastChild.className = 'help';
					legendElem.lastChild.lastChild.lastChild.id = 'HsaHelpBubble_'+helpId;
				}
				legendElem.lastChild.appendChild(document.createTextNode(Hsa.form._fcnv(xmlLegendElem)));
				parentElem.appendChild(legendElem);
			}
		}

		if (xmlElem.nodeName == 'fieldset') {
		
			// Virheilmoituksia on fieldsetin sisalla, lookahead.
			if (xmlElem.getElementsByTagName('errormsg').length > 0) {
				var errormsg_general = document.createElement('DIV');
				errormsg_general.className='errorMessage';
				errormsg_general.appendChild(document.createTextNode('Kenttien täyttämisessä tapahtui virhe. Tarkista punaisella merkityt kentät.'));
				parentElem.appendChild(errormsg_general);
			}

			var type = xmlElem.getAttribute('type');

			if (type == '2dates' || type == '1date') {
				var fieldset = document.createElement('DIV');
				fieldset.className='columns modifyInfoColumns fC';
				parentElem.appendChild(fieldset);
				parentElem = fieldset; // set parent to the new div.
			} else if (type == 'action') {
				var fieldset = document.createElement('TABLE');
				fieldset.className='fieldset_action';
				parentElem.appendChild(fieldset);
				fieldset.appendChild(document.createElement('TBODY')); // IE requires TBODY
				parentElem = fieldset.lastChild;
			} else if (type == '2columns') {
				var fieldset = document.createElement('DIV');
				fieldset.hsaType = '2columns';
				fieldset.className='columns modifyInfoColumns fC';
				parentElem.appendChild(fieldset);
				parentElem = fieldset; // set parent to the new div
			} else if (type == 'justHeadline') {
				// Do nothing else
			} else if (type == 'selectProduct') {
				var fieldset = document.createElement('DIV');
				fieldset.hsaType = 'selectProduct';
				fieldset.className='';
				parentElem.appendChild(fieldset);
				parentElem = fieldset; // set parent to the new div
			} else if (type == 'addressesOld' || type == 'addressNew') {
				var epo = parentElem;
				var fieldset = document.createElement('DIV');
				fieldset.hsaType = type;
				fieldset.className = 'addressContainer';
				epo.appendChild(fieldset);

				var epoStore = epo.lastChild;
				epo.appendChild(document.createElement('DIV'));
				epo.lastChild.className = 'clear';
				epo = epoStore;

				epo.appendChild(document.createElement('DIV'));
				epo = epo.lastChild;
				epo.className = 'tl';

				epo.appendChild(document.createElement('DIV'));
				epo = epo.lastChild;
				epo.className = 'tr';

				epo.appendChild(document.createElement('DIV'));
				epo = epo.lastChild;
				epo.className = 'br';

				epo.appendChild(document.createElement('DIV'));
				epo = epo.lastChild;
				epo.className = 'bl fC';


				parentElem = epo;
				parentElem.hsaType = type;
			} else {
				var fieldset = document.createElement('TABLE');
				fieldset.className='form';
				parentElem.appendChild(fieldset);
				fieldset.appendChild(document.createElement('TBODY')); // IE requires TBODY
				parentElem = fieldset.lastChild; // set parent to the tbody.
                
                
                if (type == 'normalOrder') {
                    fieldset.className += ' normalOrder';
                } else if (type == 'giftOrder') {
                    fieldset.className += ' giftOrder';
                }
                
                if (xmlElem.getAttribute('hiddenByDefault') == '1') {
                    fieldset.className += ' hiddenByDefault';
                }
                
				// Pakollisia kenttiä on fieldsetin sisällä, lookahead.
				var allFields = xmlElem.getElementsByTagName('field');
				if (allFields.length>0) {
					for (var a=0; a<=allFields.length-1; a++) {
						var thisField = allFields[a];
						if (thisField.getAttribute('required')) {
							parentElem.appendChild(document.createElement('TR'));
							parentElem.lastChild.appendChild(document.createElement('TD'));
							parentElem.lastChild.lastChild.className = 'noteText';
							parentElem.lastChild.lastChild.colSpan = 3;
							parentElem.lastChild.lastChild.appendChild(document.createTextNode('Tähdellä ('));
							var im = document.createElement('IMG');
                            im.className = 'required';
							im.src = '/img/symbol_required.png';
							parentElem.lastChild.lastChild.appendChild(im);
							parentElem.lastChild.lastChild.appendChild(document.createTextNode(') merkityt kentät ovat pakollisia.'));
							a = allFields.length;
						}
					}
				}
			}

			parentType = 'fieldset';


		} else if (xmlElem.nodeName == 'textset') {
			var textset = document.createElement('DIV');
                        textset.className='text';
                        parentElem.appendChild(textset);
                        parentElem = textset; // set parent to the tbody.
			parentType = 'textset';
		}


		if (xmlElem.nodeName == 'response' || xmlElem.nodeName == 'fieldset' || xmlElem.nodeName == 'textset' || xmlElem.nodeName == 'insideresponse') {
			var childNodes = xmlElem.childNodes;
			if (childNodes && childNodes.length>0) {
				for (var i=0; i <= childNodes.length-1; i++) {
					var curChild = xmlElem.childNodes[i];
					
					//console.log("--- " + xmlElem.getAttribute('type') + " " + xmlElem.nodeName);
					
					// process child nodes of a response/fieldset recursively, if any exist.
					if (curChild.nodeName == 'response' || curChild.nodeName == 'fieldset' || curChild.nodeName == 'textset') {
						this._spawnForm(parentElem, curChild, currentDepth + 1, parentType, formObject);
					} else {
						if (parentType == 'fieldset' && (xmlElem.getAttribute('type') != 'justHeadline')) {
							this._elementCreator(parentElem, curChild, currentDepth+1, formObject);
						} else if (parentType == 'textset') {
							this._elementCreatorForTextset(parentElem, curChild, currentDepth+1, formObject);
						} else if (curChild.nodeName == 'xhtml') {
							var content = curChild.childNodes[0].data;
							parentElem.innerHTML = parentElem.innerHTML + content;
						} else if (curChild.nodeName == 'js') {
							var content = curChild.childNodes[0].data;
							eval(content);
						}
					}
				}
			}
		}
	},

	_getLabel: function (inputName, xmlElement) {
		var labelValue;
		if (xmlElement != null) {
			var labelNodes = xmlElement.getElementsByTagName('label');
			for (var i=0; i<= labelNodes.length-1 && !labelValue; i++) {
				var thisNode = labelNodes[i];
				if (!thisNode.getAttribute('for')) {
					labelValue = (thisNode.firstChild ? thisNode.firstChild.nodeValue : ' '); // label can be empty
					break;
				}
			}
		}
		var defaultLabels = {
			fi: {
	        	firstName: 'Etunimi',
				lastName: 'Sukunimi',
				nullen: '(null)',
				M_ASINRO_FORCE: 'Asiakasnumero',
				M_POSTINRO_FORCE: 'Postinumero',
				M_PASSWORD_FORCE: 'Salasana'
			},
			en: {
				firstName: 'First Name'
			}
       	        };
		if (!labelValue)
			labelValue = defaultLabels[Hsa.config.lang][inputName];

		if (!labelValue)
			labelValue = defaultLabels[Hsa.config.lang]['nullen'];

		var elem = document.createElement('LABEL');
		elem.appendChild(document.createTextNode(labelValue));
		return elem;
	},

	_elementCreator: function (parentElem, xmlElement, currentDepth, formObject) {
		if (xmlElement.nodeName == '#text')
			return;

        //console.log(parentElem, xmlElement, currentDepth, formObject)

		var elems = {
			field__text: function (parentElem, xmlElement, currentDepth) {
					var xin = xmlElement.getElementsByTagName('input')[0];
                    
					var labelElem = Hsa.form._getLabel(xin.getAttribute('name'), xmlElement);
					labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');

					var inputElem = document.createElement('INPUT');
					inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					inputElem.maxLength = xin.getAttribute('maxLength') || 255;
					inputElem.type = 'text';
					inputElem.className = 'text';
					inputElem.name = xin.getAttribute('name');


                    //Street address and postal code matching
                    if( xin.getAttribute('onblurAction')=="matchAddressWithPostalCode" ){
                        jQuery(inputElem).bind("blur", function(event){
                            //var errormsg = xin.getAttribute('onblurActionErrorMsg') || "";
                            var fields = xin.getAttribute('onblurActionFields');
                            //Hsa.form.matchAddressWithPostalCode(event, fields, errormsg);

                            //delay to work with autocomplete
                            var timerId = setTimeout( "Hsa.form.matchAddressWithPostalCode('" + fields + "')", 200 );
                            jQuery(this).attr("matchTimer",timerId);
                        });
                        jQuery(inputElem).bind("focus", function(){
                            var timerIdFromInput = jQuery(this).attr("matchTimer");
                            if(timerIdFromInput){
                                clearTimeout(timerIdFromInput);
                            }
                        });
                    }



                    var autocompleteUrl = xmlElement.getAttribute('autocompleteUrl') || false;
                    if(autocompleteUrl) {
                        var minC = xmlElement.getAttribute('autocompleteMinChars') || 3;
                        jQuery(inputElem).autocomplete(autocompleteUrl,{minChars:minC, width:305,scroll:true, delay: 50});
                    }

                    
					Hsa.form._setFcnv(inputElem, xin);

					parentElem.appendChild(document.createElement('TR'));

					var errors = xmlElement.getElementsByTagName('errormsg').length>0;

					if (errors)
						parentElem.lastChild.className = 'error';

					parentElem.lastChild.appendChild(document.createElement('TH'));
					parentElem.lastChild.lastChild.appendChild(labelElem);

					parentElem.lastChild.appendChild(document.createElement('TD'));
					parentElem.lastChild.lastChild.className = 'symbol'
					
					if (xmlElement.getAttribute('required')) {
					    Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                        parentElem.lastChild.lastChild.className += ' required';
					}
					

					parentElem.lastChild.appendChild(document.createElement('TD'));
					parentElem.lastChild.lastChild.className = 'field';
					parentElem.lastChild.lastChild.appendChild(inputElem);

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						parentElem.lastChild.lastChild.appendChild(errormsg);
					}

					parentElem.lastChild.appendChild(document.createElement('TD')); // empty 4th TD

			},
			
			field__password: function (parentElem, xmlElement, currentDepth) {

					var xin = xmlElement.getElementsByTagName('input')[0];

					var labelElem = Hsa.form._getLabel(xin.getAttribute('name'), xmlElement);
					labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');

					var inputElem = document.createElement('INPUT');
					inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					inputElem.maxLength = xin.getAttribute('maxLength') || 255;
					inputElem.type = 'password';
					inputElem.className = 'password text';
					inputElem.name = xin.getAttribute('name');

					Hsa.form._setFcnv(inputElem, xin);

					parentElem.appendChild(document.createElement('TR'));

					var errors = xmlElement.getElementsByTagName('errormsg').length>0;

					if (errors)
						parentElem.lastChild.className = 'error';

					parentElem.lastChild.appendChild(document.createElement('TH'));
					parentElem.lastChild.lastChild.appendChild(labelElem);

					parentElem.lastChild.appendChild(document.createElement('TD'));
					parentElem.lastChild.lastChild.className = 'symbol';
					if (xmlElement.getAttribute('required')) {
					    Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                        parentElem.lastChild.lastChild.className += ' required';
					}

					parentElem.lastChild.appendChild(document.createElement('TD'));
					parentElem.lastChild.lastChild.className = 'field';
					parentElem.lastChild.lastChild.appendChild(inputElem);

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						parentElem.lastChild.lastChild.appendChild(errormsg);
					}

					parentElem.lastChild.appendChild(document.createElement('TD')); // empty 4th TD

			},
			

			field__telnum: function (epo, xmlElement, currentDepth) {

					var xina = xmlElement.getElementsByTagName('select')[0];
					var xinb = xmlElement.getElementsByTagName('input')[0];

					var labelElem = Hsa.form._getLabel(xina.getAttribute('name'), xmlElement);
					labelElem.htmlFor = xina.getAttribute('id') || xina.getAttribute('name');

					var selectElem = document.createElement('SELECT');
					selectElem.id = xina.getAttribute('id') || xina.getAttribute('name');

					selectElem.className = 'text areaCode';
					selectElem.name = xina.getAttribute('name');

					for (var i=0; i< xina.childNodes.length; i++) {
						var cn = xina.childNodes[i];
						if ( cn.nodeType != 1 )
                                    			continue;
						var no = document.createElement('OPTION');
						no.selected = ((cn.getAttribute('value') == xina.getAttribute('selectedValue')) || (cn.getAttribute('selected') == 'selected')) ? true : false;
						no.value = cn.getAttribute('value');
						selectElem.appendChild(no);
						no.text = Hsa.form._fcnv(cn);
					}

					var inputElem = document.createElement('INPUT');
					inputElem.id = xinb.getAttribute('id') || xinb.getAttribute('name');
					inputElem.maxLength = xinb.getAttribute('maxLength') || 255;
					inputElem.type = 'text';
					inputElem.className = 'text noAreaCode';
					inputElem.name = xinb.getAttribute('name');
					Hsa.form._setFcnv(inputElem, xinb);

					var hyphenElem = document.createElement('SPAN');
					hyphenElem.appendChild(document.createTextNode('-'));
					hyphenElem.className = 'hyphen';

					epo.appendChild(document.createElement('TR'));
					var errors = xmlElement.getElementsByTagName('errormsg').length>0;
					if (errors)
						epo.lastChild.className = 'error';

					epo = epo.lastChild;

					epo.appendChild(document.createElement('TH'));
					epo.lastChild.appendChild(labelElem);

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'symbol';
					if (xmlElement.getAttribute('required')) {
					    Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                        parentElem.lastChild.lastChild.className += ' required';
					}					

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'field';
					epo.lastChild.appendChild(selectElem);
					epo.lastChild.appendChild(hyphenElem);
					epo.lastChild.appendChild(inputElem);

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						epo.lastChild.appendChild(errormsg);
					}


					epo.appendChild(document.createElement('TD')); // empty 4th TD
					
			},

			field__select: function (epo, xmlElement, currentDepth) {

					var xina = xmlElement.getElementsByTagName('select')[0];

					var labelElem = Hsa.form._getLabel(xina.getAttribute('name'), xmlElement);
					labelElem.htmlFor = xina.getAttribute('id') || xina.getAttribute('name');

					var selectElem = document.createElement('SELECT');
					selectElem.id = xina.getAttribute('id') || xina.getAttribute('name');

					selectElem.className = 'text';
					selectElem.name = xina.getAttribute('name');

					for (var i=0; i< xina.childNodes.length; i++) {
						var cn = xina.childNodes[i];
						if ( cn.nodeType != 1 )
                                    			continue;
						var no = document.createElement('OPTION');
						no.selected = ((cn.getAttribute('value') == xina.getAttribute('selectedValue')) || (cn.getAttribute('selected') == 'selected')) ? true : false;
						no.value = cn.getAttribute('value');
						selectElem.appendChild(no);
						no.text = Hsa.form._fcnv(cn);
					}

					epo.appendChild(document.createElement('TR'));
					var errors = xmlElement.getElementsByTagName('errormsg').length>0;
					if (errors)
						epo.lastChild.className = 'error';

					epo = epo.lastChild;

					epo.appendChild(document.createElement('TH'));
					epo.lastChild.appendChild(labelElem);

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'symbol';
					if (xmlElement.getAttribute('required')) {
					    Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                        parentElem.lastChild.lastChild.className += ' required';
					}

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'field';
					epo.lastChild.appendChild(selectElem);

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						epo.lastChild.appendChild(errormsg);
					}

					epo.appendChild(document.createElement('TD')); // empty 4th TD
					
			},

			field__buttons: function (parentElem, xmlElement, currentDepth) {
					parentElem.appendChild(document.createElement('TR'));

					var inBetween = (xmlElement.getAttribute('class') == 'inBetween' ? true : false);
                    var colSpan = (xmlElement.getAttribute('class') == 'colspan' ? true : false);
                    
					// Jos 1, niin ylim. tdx2.
					if (xmlElement.getElementsByTagName('input').length == 1 && !colSpan) {
						parentElem.lastChild.appendChild(document.createElement('TD')); // empty td
						parentElem.lastChild.appendChild(document.createElement('TD')); // empty td
                                                if (inBetween)
                                                        parentElem.lastChild.className = 'buttonsInBetween'; // buttons class not needed.
					} else {
						if (inBetween)
							parentElem.lastChild.className = 'buttons buttonsInBetween';
						else
							parentElem.lastChild.className = 'buttons';
					}

					var td = document.createElement('TD');
					if (xmlElement.getElementsByTagName('input').length != 1 || colSpan)
						td.colSpan=4;
					parentElem.lastChild.appendChild(td);

					for (var i=0; i< xmlElement.childNodes.length; i++) {
						var cn = xmlElement.childNodes[i];
						if ( cn.nodeType != 1 )
                                continue;
                            
			                if (cn.nodeName == 'input' && cn.getAttribute('type') == 'button') {
							var inputButton;
							if (cn.getAttribute('class') == 'submit') {
								inputButton = document.createElement('INPUT');
								inputButton.type= 'button';
								if (cn.getAttribute('value') == 'Jatka kirjautumatta') {
								  inputButton.className='button buttonMedium';
								} else {
								  inputButton.className='button buttonStrong buttonLarge';
								}
								inputButton.value = 'Jatka'; // Default
								inputButton.onclick = function() { return Hsa.form.submitButton(inputButton); };
								if (cn.getAttribute('value'))
									inputButton.value = cn.getAttribute('value');
							} else if (cn.getAttribute('class') == 'cancel') {
								inputButton = document.createElement('INPUT');
								inputButton.type= 'button';
								inputButton.className = 'buttonCancel';
								inputButton.value = 'Keskeytä'; // Default
								inputButton.onclick = function() { return Hsa.form.abortButton(this); };
								if (cn.getAttribute('value'))
									inputButton.value = cn.getAttribute('value');
							} else if (cn.getAttribute('class') == 'back') {
								inputButton = document.createElement('BUTTON');
								inputButton.className = 'button buttonBack buttonMedium';
								var valu = 'Takaisin'; // Default
								if (cn.getAttribute('value'))
									valu = cn.getAttribute('value');
								// inputButton.value = valu;
								if (cn.getAttribute('backToPhase')) {
									inputButton.setAttribute('data-back-to-phase', cn.getAttribute('backToPhase'))
								}
								inputButton.onclick = function() { return Hsa.form.backButton(this); };
								inputButton.appendChild(document.createElement('SPAN'));
								inputButton.lastChild.appendChild(document.createTextNode(valu));
							} else {
								alert('invalid button class.' + cn.getAttribute('class'));
							}
							if (cn.getAttribute('disabled') == 'disabled') {
							    inputButton.disabled = true;
							    inputButton.className = 'button buttonBasic buttonLarge buttonDisabled';
							}
							if (cn.getAttribute('id')) {
							    inputButton.id = cn.getAttribute('id');
							}
							if (inputButton && cn.getAttribute('name'))
								inputButton.name = cn.getAttribute('name');

							td.appendChild(inputButton);
						}

					}
				},

			field__radio: function (epo, xmlElement, currentDepth, formObject) {
					if (xmlElement.parentNode.getAttribute('type') == 'addressesOld') {
						var xin = xmlElement.getElementsByTagName('input')[0];

						var inputElem = document.createElement('input');
						inputElem.type = 'radio';
						Hsa.form._setFcnv(inputElem, xin);

						inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
						inputElem.name = xin.getAttribute('name');

						var labelElem = Hsa.form._getLabel(xmlElement.getElementsByTagName('input')[0].getAttribute('name'), xmlElement);
						labelElem.className = 'strong';
						labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');
						epo.appendChild(inputElem);
						if (xin.getAttribute('checked'))
							Hsa.form._radioChecked(inputElem);
						epo.appendChild(labelElem);

						var subElems = xmlElement.getElementsByTagName('field');

						var addresstable;
						if (subElems.length>0) {
							var address = document.createElement('TABLE');
							address.className = 'form chooseOldAddress';
							if (!xin.getAttribute('checked'))
								address.style.display = 'none';
							else
								Hsa.form.openAddressField = address;

							address.appendChild(document.createElement('TBODY'));

							jQuery(inputElem).bind('click', function(e) {
												        var target = window.event ? window.event.srcElement : e ? e.target : null;
													Hsa.form._radioChecked(target);
													if (Hsa.form.openAddressField)
														jQuery(Hsa.form.openAddressField).fadeOut(500);
													Hsa.form.openAddressField = address;
													jQuery(address).fadeIn(500);
												}, false);
						} else {
							jQuery(inputElem).bind('click', function(e) {
							        var target = window.event ? window.event.srcElement : e ? e.target : null;
								Hsa.form._radioChecked(target);
								if (Hsa.form.openAddressField)
									jQuery(Hsa.form.openAddressField).fadeOut(500);
								Hsa.form.openAddressField = null;
							}, false);
						}

						for (var i=0; i< subElems.length; i++) {
							var cn = subElems[i];
							if ( cn.nodeType != 1 )
 	                             				continue;
							if (cn.getAttribute('type') != 'radioAddress')
								continue;
							if (i%2 != 1)
								address.lastChild.appendChild(document.createElement('TR'));

							address.lastChild.lastChild.appendChild(document.createElement('TD'));

							if (i==0) {
								address.lastChild.lastChild.lastChild.className = 'address first';
							} else {
								address.lastChild.lastChild.lastChild.className = 'address';
							}

							var xinin = cn.getElementsByTagName('input')[0];

							var inputElemB = document.createElement('INPUT');
							inputElemB.type = 'radio';
							inputElemB.className = 'radio';
							inputElemB.id = xinin.getAttribute('id') || xinin.getAttribute('name');
							inputElemB.name = xinin.getAttribute('name');
							Hsa.form._setFcnv(inputElemB, xinin);

							address.lastChild.lastChild.lastChild.appendChild(inputElemB);

							var labelElemB = document.createElement('LABEL');
							labelElemB.htmlFor = inputElemB.id;

							var addressElement = cn.getElementsByTagName('address')[0];
							if (addressElement)
								Hsa.form._xmlTree2Html(labelElemB, addressElement, 100);

							address.lastChild.lastChild.lastChild.appendChild(labelElemB);
							epo.appendChild(address);

							if (xinin.getAttribute('checked'))
								Hsa.form._radioChecked(inputElemB);

							jQuery(inputElemB).bind('click', function(e) { var target = window.event ? window.event.srcElement : e ? e.target : null; Hsa.form._radioChecked(target); Hsa.form._addressRadioSelected(e); }, false);
						} // for


					} else if ( xmlElement.parentNode.getAttribute('type') == 'addressNew') {

						var xin = xmlElement.getElementsByTagName('input')[0];

						var inputElem = document.createElement('input');
						inputElem.type = 'radio';
						Hsa.form._setFcnv(inputElem, xin);

						inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
						inputElem.name = xin.getAttribute('name');

						var labelElem = Hsa.form._getLabel(xmlElement.getElementsByTagName('input')[0].getAttribute('name'), xmlElement);
						labelElem.className = 'strong';
						labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');
						epo.appendChild(inputElem);
						if (xin.getAttribute('checked'))
							Hsa.form._radioChecked(inputElem);

						epo.appendChild(labelElem);

						epo.appendChild(document.createElement('DIV'));
						epo = epo.lastChild;

						if (!xin.getAttribute('checked'))
							epo.style.display = 'none';
						else
							Hsa.form.openAddressField = epo;

						jQuery(inputElem).bind('click', function(e) {
													if (Hsa.form.openAddressField)
														jQuery(Hsa.form.openAddressField).fadeOut(500);
													Hsa.form.openAddressField = epo;
												        var target = window.event ? window.event.srcElement : e ? e.target : null;
													Hsa.form._radioChecked(target);
													jQuery(epo).fadeIn(500);
												}, false);


						var inside = xmlElement.getElementsByTagName('insideresponse')[0];
						var parentType = 'insideresponse';
						Hsa.form._spawnForm(epo, inside, currentDepth + 1, parentType, formObject);


					} else {
						// Normal field__radio

						epo.appendChild(document.createElement('TR'));
						var errors = xmlElement.getElementsByTagName('errormsg').length>0;
						if (errors)
							epo.lastChild.className = 'error';
	
	                                        epo = epo.lastChild;

						var radioInputs = xmlElement.getElementsByTagName('input');
						var xin = radioInputs[0];

						var labelElem = Hsa.form._getLabel(xin.getAttribute('name'), xmlElement);

	                                        epo.appendChild(document.createElement('TH'));
	                                        epo.lastChild.appendChild(labelElem);

	                                        epo.appendChild(document.createElement('TD'));
	      	                                epo.lastChild.className = 'symbol';
	      	                                if (xmlElement.getAttribute('required')) {
                                                Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                                                parentElem.lastChild.lastChild.className += ' required';
                                            }

	                                        epo.appendChild(document.createElement('TD'));
	       	                                epo.lastChild.className = 'field';

	                                        for (var i=0; i< radioInputs.length; i++) {
	       	                                        var cn = radioInputs[i];
	       	                                        if ( cn.nodeType != 1 )
	                                                	continue;
	                                                var no = document.createElement('INPUT');
							no.id = cn.getAttribute('id'); // todo: die, id on pakollinen
							no.name = cn.getAttribute('name');

							no.type = 'radio';
	                                                no.value = cn.getAttribute('value');
							jQuery(no).bind('click', function(e) { var target = window.event ? window.event.srcElement : e ? e.target : null; Hsa.form._radioChecked(target) });
							epo.lastChild.appendChild(no);
							if (cn.getAttribute('checked'))
								Hsa.form._radioChecked(no);

							var labelElem = document.createElement('LABEL');
							labelElem.htmlFor = no.id;
							Hsa.form._xmlTree2Html(labelElem, cn, 100);

							epo.lastChild.appendChild(labelElem);
							epo.lastChild.appendChild(document.createElement('BR'));
	                                        }

						if (errors) {
							var errormsg = document.createElement('SPAN');
							errormsg.className='fieldError';
							errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
							epo.lastChild.appendChild(errormsg);
						}

                                 	       epo.appendChild(document.createElement('TD')); // empty 4th TD
					}

				},

			field__textarea: function (epo, xmlElement, currentDepth) {

					var xina = xmlElement.getElementsByTagName('textarea')[0];

					var labelElem = Hsa.form._getLabel(xina.getAttribute('name'), xmlElement);
					labelElem.htmlFor = xina.getAttribute('id') || xina.getAttribute('name');

					var textareaElem = document.createElement('TEXTAREA');
					textareaElem.id = xina.getAttribute('id') || xina.getAttribute('name');

					textareaElem.hsaMaxLength = xina.getAttribute('maxLength') || 255;

					var maxTextElem = document.createElement('DIV');
					maxTextElem.className = 'counter';

					textareaElem.hsaUpdateMaxTextLengthTo = maxTextElem;
					textareaElem.hsaAlertedMaxLength = false;

					textareaElem.onkeyup = function () { Hsa.form.charCount( this); };

					textareaElem.className = 'text';
					textareaElem.name = xina.getAttribute('name');
					Hsa.form._setFcnv(textareaElem, xina);
					Hsa.form.charCount(textareaElem);

					epo.appendChild(document.createElement('TR'));
					var errors = xmlElement.getElementsByTagName('errormsg').length>0;
					if (errors)
						epo.lastChild.className = 'error';

					epo = epo.lastChild;

					epo.appendChild(document.createElement('TH'));
					epo.lastChild.appendChild(labelElem);
					epo.lastChild.appendChild(maxTextElem);

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'symbol';
					if (xmlElement.getAttribute('required')) {
					    Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                        parentElem.lastChild.lastChild.className += ' required';
					}

					epo.appendChild(document.createElement('TD'));
					epo.lastChild.className = 'field';
					epo.lastChild.appendChild(textareaElem);

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						epo.lastChild.appendChild(errormsg);
					}

					epo.appendChild(document.createElement('TD')); // empty 4th TD

					Hsa.form.charCount( textareaElem);
					
			},

			field__action: function (parentElem, xmlElement, currentDepth) {
					var inputButton = document.createElement('input');
					inputButton.type = 'submit';
					Hsa.form._setFcnv(inputButton, xmlElement.getElementsByTagName('label')[0]);
					parentElem.appendChild(inputButton);
				},

			field__hidden: function (parentElem, xmlElement, currentDepth) {
                // Hidden fields shouldn't be inside a table so I commented these out. -Tuomas
                
				parentElem.appendChild(document.createElement('TR'));
				parentElem.lastChild.appendChild(document.createElement('TH'));
				parentElem.lastChild.appendChild(document.createElement('TD'));
				parentElem.lastChild.lastChild.className = 'symbol';
				parentElem.lastChild.appendChild(document.createElement('TD'));

				var childNodes = xmlElement.getElementsByTagName('input');
				if (childNodes && childNodes.length>0) {
					for (var i=0; i <= childNodes.length-1; i++) {
						var xin = childNodes[i];

						var inputElem = document.createElement('INPUT');
						inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
						inputElem.type = 'hidden';
						inputElem.className = 'hidden';
						inputElem.name = xin.getAttribute('name');
						Hsa.form._setFcnv(inputElem, xin);

						parentElem.appendChild(inputElem);
					}
				}
			},

			field__calendar: function (parentElem, xmlElement, currentDepth, formObject) {
					if (parentElem.nodeName != 'DIV') {
						alert('calendar not allowed here, not a div');
						return;
					}
					parentElem.appendChild(document.createElement('DIV'));
					if (parentElem.childNodes.length==1) {
						parentElem.lastChild.className='part1of3 startDay';
					} else if (parentElem.childNodes.length==2) {
						parentElem.lastChild.className='part2of3 startDay';
					}
					var errors = xmlElement.getElementsByTagName('errormsg').length>0;
					if (errors)
						parentElem.lastChild.className += ' error';

					if (xmlElement.getElementsByTagName('label')[0]) {
						parentElem.lastChild.appendChild(document.createElement('DIV'));
						parentElem.lastChild.lastChild.className = 'text';
						parentElem.lastChild.lastChild.appendChild(document.createElement('H4'));
						parentElem.lastChild.lastChild.lastChild.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('label')[0])));
					}

					parentElem.lastChild.appendChild(document.createElement('DIV'));
					parentElem.lastChild.lastChild.className='tl';

					var inputElem = document.createElement('INPUT');
					var xin = xmlElement.getElementsByTagName('input')[0];
					inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					inputElem.type = 'hidden';
					inputElem.className = 'hidden';
					inputElem.name = xin.getAttribute('name');
					Hsa.form._setFcnv(inputElem, xin);
					parentElem.lastChild.lastChild.appendChild(inputElem);


					var fieldName = xin.getAttribute('name');
					var calendarId = xin.getAttribute('name') + '_calendar';
					var putInsideDivObj = parentElem.lastChild.lastChild;
					var changeAffectsId = xmlElement.getAttribute('changeAffects') + '_calendar';
					var xmlParams = xmlElement.getAttribute('xmlParams');
					var updateDurationTextId = xmlElement.getAttribute('updateDuration');
					var hiddenInput = inputElem;
					var valueDay = xmlElement.getAttribute('valueDay');
					var valueMonth = xmlElement.getAttribute('valueMonth');
					var valueYear = xmlElement.getAttribute('valueYear');
					var apiAction = formObject.ajaxApiMethodName;

					var cal = new HsaCalendar(calendarId, putInsideDivObj, hiddenInput, changeAffectsId, xmlParams, updateDurationTextId, valueDay, valueMonth, valueYear, fieldName, apiAction);
					cal.setSubscription(xmlElement.getAttribute('initialSubscription'));
					cal.create();
					inputElem.hsa_HsaCalendarObject = cal;

					if (errors) {
						var errormsg = document.createElement('SPAN');
						errormsg.className='fieldError';
						errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
						parentElem.lastChild.lastChild.appendChild(errormsg);
					}
				},

			field__duration: function (parentElem, xmlElement, currentDepth) {
					if (parentElem.nodeName != 'DIV') {
						alert('calendar not allowed here');
						return;
					}
					var label1 = Hsa.form._fcnv(xmlElement.getElementsByTagName('label1')[0]);
					var duration1 = xmlElement.getElementsByTagName('duration1')[0];
					var label2 = Hsa.form._fcnv(xmlElement.getElementsByTagName('label2')[0]);
					var duration2 = xmlElement.getElementsByTagName('duration2')[0];
					var noteText_elem = xmlElement.getElementsByTagName('noteText')[0];
					var noteText = Hsa.form._fcnv(noteText_elem);
					var noteText_elem2 = xmlElement.getElementsByTagName('noteText2')[0];
					var noteText2 = Hsa.form._fcnv(noteText_elem2);

					var dur = document.createElement('DIV');
					if (label2 && duration2)
						dur.className='part3of3 duration';
					else
						dur.className='part2and3of3 startDayText';

					dur.appendChild(document.createElement('P'));
					dur.lastChild.appendChild(document.createElement('SPAN'));
					dur.lastChild.lastChild.className='heading';
					dur.lastChild.lastChild.appendChild(document.createTextNode(label1));

					dur.lastChild.appendChild(document.createElement('SPAN'));
					dur.lastChild.lastChild.id = duration1.getAttribute('name');
					dur.lastChild.lastChild.className='date';
					dur.lastChild.lastChild.appendChild(document.createTextNode('-'));

					if (label2 && duration2) {
						dur.lastChild.appendChild(document.createElement('SPAN'));
						dur.lastChild.lastChild.className='heading';
						dur.lastChild.lastChild.appendChild(document.createTextNode(label2));

						dur.lastChild.appendChild(document.createElement('SPAN'));
						dur.lastChild.lastChild.id = duration2.getAttribute('name');
						dur.lastChild.lastChild.className='date';
						dur.lastChild.lastChild.appendChild(document.createTextNode('-'));
					}

					dur.appendChild(document.createElement('P'));
					if (noteText_elem.getAttribute('id') && dur.lastChild) {
						dur.lastChild.id = noteText_elem.getAttribute('id');
					}
					
					dur.lastChild.appendChild(document.createTextNode(noteText));
					dur.appendChild(document.createElement('P'));
					dur.lastChild.appendChild(document.createTextNode(noteText2));

					parentElem.appendChild(dur);
				},

			field__pvm: function (parentElem, xmlElement, currentDepth) {
					var labelElem = Hsa.form._getLabel(xmlElement.getElementsByTagName('input')[0].getAttribute('name'), xmlElement);
					var inputElem = document.createElement('input');
					inputElem.type = 'text';
					Hsa.form._setFcnv(inputElem, xmlElement.getElementsByTagName('input')[0]);
					parentElem.appendChild(labelElem);
					parentElem.appendChild(inputElem);
				},

			field__checkbox: function (parentElem, xmlElement, currentDepth) {
					var xin = xmlElement.getElementsByTagName('input')[0];

					var labelElem = Hsa.form._getLabel(xmlElement.getElementsByTagName('input')[0].getAttribute('name'), xmlElement);

					var inputElem = document.createElement('INPUT');
					inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					inputElem.type = 'checkbox';
					inputElem.className = 'checkbox';
					inputElem.name = xin.getAttribute('name');
					Hsa.form._setFcnv(inputElem, xin);

					labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');

					parentElem.appendChild(document.createElement('TR'));

					var errors = xmlElement.getElementsByTagName('errormsg').length>0;

					var tight = (xmlElement.getAttribute('tight') == '1' ? 'tight' : '');
					parentElem.lastChild.className = tight;

                                        if (errors)
                                                parentElem.lastChild.className = tight + ' error';

					if (xmlElement.getAttribute('wide')) {
					} else {
	                                        parentElem.lastChild.appendChild(document.createElement('TH'));
	       	                                parentElem.lastChild.lastChild.appendChild(labelElem);
	                                        parentElem.lastChild.appendChild(document.createElement('TD'));
                                            parentElem.lastChild.lastChild.className = 'symbol';
                                            if (xmlElement.getAttribute('required')) {
                                                Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                                                parentElem.lastChild.lastChild.className += ' required';
                                            }
					}

                                        parentElem.lastChild.appendChild(document.createElement('TD'));
					if (xmlElement.getAttribute('wide')) {
						parentElem.lastChild.lastChild.className = 'fieldMultiple'; // TODO: was: text
						parentElem.lastChild.lastChild.colSpan = 4;
					} else {
	                                        parentElem.lastChild.lastChild.className = 'fieldCheckbox';
					}
                                        parentElem.lastChild.lastChild.appendChild(inputElem);
					if (xin.getAttribute('checked'))
						inputElem.checked = 'checked';

					var labelNodes = xmlElement.getElementsByTagName('sublabel');

					for (var i=0; i<= labelNodes.length-1 && !labelValue; i++) {
						var thisNode = labelNodes[i];
			
						if (thisNode.getAttribute('for') == inputElem.id) {
							var labelValue = (thisNode.firstChild ? thisNode.firstChild.nodeValue : ' '); // label can be empty
							var inputLabel = document.createElement('LABEL');
							inputLabel.appendChild(document.createTextNode(labelValue));
							inputLabel.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');
							parentElem.lastChild.lastChild.appendChild(inputLabel);
							break;
						}
					}

                                        if (errors) {
                                                var errormsg = document.createElement('SPAN');
                                                errormsg.className='fieldError';
                                                errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
                                                parentElem.lastChild.lastChild.appendChild(errormsg);
                                        }

					if (!xmlElement.getAttribute('wide'))
						parentElem.lastChild.appendChild(document.createElement('TD')); // empty 4th TD

			},
			
			field__captcha: function (parentElem, xmlElement, currentDepth) {
					var xin = xmlElement.getElementsByTagName('input')[0];
                    
                    var labelElem = Hsa.form._getLabel(xmlElement.getElementsByTagName('input')[0].getAttribute('name'), xmlElement);
					
					var inputElem = document.createElement('INPUT');
					inputElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					inputElem.maxLength = xin.getAttribute('maxLength') || 255;
					inputElem.type = 'text';
					inputElem.className = 'text captcha';
					inputElem.name = xin.getAttribute('name');
					
					Hsa.form._setFcnv(inputElem, xin);
                    
					labelElem.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');
                    
					parentElem.appendChild(document.createElement('TR'));
                    
					var errors = xmlElement.getElementsByTagName('errormsg').length>0;

					var tight = (xmlElement.getAttribute('tight') == '1' ? 'tight' : '');
					parentElem.lastChild.className = tight;

                    if (errors)
                        parentElem.lastChild.className = tight + ' error';

					if (xmlElement.getAttribute('wide')) {
					    
					} else {
                        parentElem.lastChild.appendChild(document.createElement('TH'));
                        parentElem.lastChild.lastChild.appendChild(labelElem);
                        parentElem.lastChild.appendChild(document.createElement('TD'));
                        parentElem.lastChild.lastChild.className = 'symbol';
                        if (xmlElement.getAttribute('required')) {
                            Hsa.form._printSpacerImage(parentElem.lastChild.lastChild);
                            parentElem.lastChild.lastChild.className += ' required';
                        }
					}

                    parentElem.lastChild.appendChild(document.createElement('TD'));
                    
					if (xmlElement.getAttribute('wide')) {
						parentElem.lastChild.lastChild.className = 'fieldMultiple captcha'; // TODO: was: text
						parentElem.lastChild.lastChild.colSpan = 4;
						
						var imageElem = document.createElement('IMG');
                        imageElem.className = 'captcha'
                        imageElem.src = xmlElement.getAttribute('source');
                        parentElem.lastChild.lastChild.appendChild(imageElem);
						
						parentElem.lastChild.lastChild.appendChild(labelElem);
					    parentElem.lastChild.lastChild.appendChild(document.createElement('BR'));
					} else {
                        parentElem.lastChild.lastChild.className = 'fieldCheckbox';
					}
                    
                    parentElem.lastChild.lastChild.appendChild(inputElem);
                    
                    
					
					
					/*
					if (xin.getAttribute('checked'))
						inputElem.checked = 'checked';
                    */
					var labelNodes = xmlElement.getElementsByTagName('sublabel');

					for (var i=0; i<= labelNodes.length-1 && !labelValue; i++) {
						var thisNode = labelNodes[i];
			
						if (thisNode.getAttribute('for') == inputElem.id) {
							var labelValue = (thisNode.firstChild ? thisNode.firstChild.nodeValue : ' '); // label can be empty
							var inputLabel = document.createElement('LABEL');
							inputLabel.appendChild(document.createTextNode(labelValue));
							inputLabel.htmlFor = xin.getAttribute('id') || xin.getAttribute('name');
							parentElem.lastChild.lastChild.appendChild(inputLabel);
							break;
						}
					}

                    if (errors) {
                        var errormsg = document.createElement('SPAN');
                        errormsg.className='fieldError';
                        errormsg.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('errormsg')[0])));
                        parentElem.lastChild.lastChild.appendChild(errormsg);
                    }

					if (!xmlElement.getAttribute('wide'))
						parentElem.lastChild.appendChild(document.createElement('TD')); // empty 4th TD

			},

			notetext__: function (parentElem, xmlElement, currentDepth) {
					var notenode;
					if (parentElem.hsaType == 'addressesOld') {
						parentElem.appendChild(document.createElement('DIV'));
						notenode = parentElem.lastChild;
						notenode.className='noteText';
					} else if (xmlElement.getAttribute('wide')) {
						parentElem.appendChild(document.createElement('TR'));
						parentElem.lastChild.appendChild(document.createElement('TD'));
						notenode = parentElem.lastChild.lastChild;
						notenode.colSpan=4;
						notenode.className='noteText noteTextFull';
					} else {
						parentElem.appendChild(document.createElement('TR'));
						parentElem.lastChild.appendChild(document.createElement('TD'));
						parentElem.lastChild.appendChild(document.createElement('TD'));
						parentElem.lastChild.lastChild.className='symbol';
						parentElem.lastChild.appendChild(document.createElement('TD'));
						notenode = parentElem.lastChild.lastChild;
						notenode.colSpan=2;
						notenode.className='noteText';
					}
					Hsa.form._xmlTree2Html(notenode, xmlElement, 100);
					if (xmlElement.getAttribute('id') && notenode) {
						notenode.id = xmlElement.getAttribute('id');
					}
					
			},
			text__: function (parentElem, xmlElement, currentDepth) {
				parentElem.appendChild(document.createElement('TR'));
				parentElem.lastChild.appendChild(document.createElement('TD'));
				var notenode = parentElem.lastChild.lastChild;
				notenode.colSpan=4;
				notenode.className='text';
				Hsa.form._xmlTree2Html(notenode, xmlElement, 100);
			},
			field__customerInfo: function (parentElem, xmlElement, currentDepth) {
				if (parentElem.hsaType != '2columns') {
					alert('customerInfo allowed only inside 2column-fieldset.');
					return;
				}

				parentElem.appendChild(document.createElement('DIV'));
				parentElem.lastChild.className='part1of2 customerInfo';
				parentElem = parentElem.lastChild;

				parentElem.appendChild(document.createElement('DIV'));
				parentElem.lastChild.className='text';
				parentElem.lastChild.appendChild(document.createElement('H2'));
				parentElem.lastChild.lastChild.className='em';
				parentElem.lastChild.lastChild.appendChild(document.createElement('EM'));
				parentElem.lastChild.lastChild.lastChild.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('label')[0])));

				parentElem.lastChild.appendChild(document.createElement('P'));
				parentElem.lastChild.lastChild.appendChild(document.createElement('SPAN'));
				parentElem.lastChild.lastChild.lastChild.className='name';
				parentElem.lastChild.lastChild.lastChild.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('name')[0])));

				Hsa.form._xmlTree2Html(parentElem.lastChild.lastChild, xmlElement.getElementsByTagName('address')[0]);
			},

			field__subscriptionInfo: function (epo, xmlElement, currentDepth) {
                                if (epo.hsaType != '2columns') {
                                        alert('subscriptionInfo allowed only inside 2column-fieldset.');
                                        return;
                                }

				epo.appendChild(document.createElement('DIV'));
				epo.lastChild.className='part2of2 subscriptionInfo';
				epo.lastChild.appendChild(document.createElement('DIV'));
				epo = epo.lastChild.lastChild;

				epo.className='text';
				epo.appendChild(document.createElement('H2'));
				epo.lastChild.className='em';
				epo.lastChild.appendChild(document.createElement('EM'));
				epo.lastChild.lastChild.appendChild(document.createTextNode(Hsa.form._fcnv(xmlElement.getElementsByTagName('label')[0])));

				epo.appendChild(document.createElement('P'));
				var sublabelElement = xmlElement.getElementsByTagName('sublabel')[0];
				if (sublabelElement)
					Hsa.form._xmlTree2Html(epo.lastChild, sublabelElement, 100);

				var xin = xmlElement.getElementsByTagName('select')[0];
				if (xin) {
					var selectElem = document.createElement('SELECT');
					selectElem.id = xin.getAttribute('id') || xin.getAttribute('name');
					selectElem.name = xin.getAttribute('name');

					if (xin.getAttribute('updatesCalendar')) {
						selectElem._hsa_updatesCalendar = xin.getAttribute('updatesCalendar');
						selectElem._hsa_updatesCalendar2 = xin.getAttribute('updatesCalendar2');
						selectElem.onchange = function() { function setSubs(calObj, subscription) {
											   if (calObj) {
												calObj.hsa_HsaCalendarObject.setSubscription(subscription);
												calObj.hsa_HsaCalendarObject.create();
											   }
										   }
										   setSubs(document.getElementById(this._hsa_updatesCalendar), this.value);
										   setSubs(document.getElementById(this._hsa_updatesCalendar2), this.value);
								      };
					}

					for (var i=0; i< xin.childNodes.length; i++) {
						var cn = xin.childNodes[i];
						if ( cn.nodeType != 1 )
		                      			continue;
						var no = document.createElement('OPTION');
						no.selected = ((cn.getAttribute('value') == xin.getAttribute('selectedValue')) || (cn.getAttribute('selected') == 'selected')) ? true : false;
						no.value = cn.getAttribute('value');
						selectElem.appendChild(no);
						no.text = Hsa.form._fcnv(cn);
					}
					epo.appendChild(selectElem);
				} // if xin

			},

			field__selectProduct: function (epo, xmlElement, currentDepth) {
				var xInputElems = xmlElement.getElementsByTagName('input');
				var methodName = xmlElement.getAttribute('methodName') || 'tilausvalitsin-1';
				var xInputIds = new Array();
                                for (var i=0; i<= xInputElems.length-1; i++) {
					var xie = xInputElems[i];
	                                var inputElem = document.createElement('input');
	                                inputElem.type = xie.getAttribute('type');
					inputElem.name = xie.getAttribute('name');
					inputElem.id = xie.getAttribute('id') || xie.getAttribute('name');
					inputElem.value = xie.getAttribute('value');
					xInputIds.push(inputElem.id);
					epo.appendChild(inputElem);
				}

				var productSelector = new HsaProductSelector(epo, xInputIds, methodName);
				epo._hsa_productSelector = productSelector;
				Hsa.form._current_hsa_productSelector = productSelector;
			},

			field__paymentMethods: function (epo, xmlElement, currentDepth) {
					epo.appendChild(document.createElement('TR'));
					epo.lastChild.appendChild(document.createElement('TD'));
					epo = epo.lastChild.lastChild;
					epo.className = 'choosePaymentMethod';
					epo.colSpan=4;

					// Prototype doesn't serialize the form correctly, so this hidden field is populated with onclick to contain the right button causing the submission.
					var hid = document.createElement('INPUT');
					hid.type = 'hidden';
					hid.name = 'paymentMethod';
					hid.id = 'input_paymentMethod';
					epo.appendChild(hid);

					for (var i=0; i< xmlElement.childNodes.length; i++) {
						var cn = xmlElement.childNodes[i];
						if ( cn.nodeType != 1) 
						    continue;

						if (cn.nodeName == 'payment') {
						      var buttonName = cn.getAttribute('button');
						      var aElem = document.createElement('A');
						      aElem.className = 'button buttonPS buttonPayment';
						      switch (buttonName) {
							    case 'sampo': case 'handelsbanken': case 'alandsbanken':
								  aElem.className += ' buttonPaymentWide';
								  break;
							    case 'nordea': case 'op': case 'tapiola': case 'aktia': case 'lasku': case 'saastopankki': case 's-pankki': case 'credit':
								  aElem.className += ' buttonPaymentMedium';
								  break;
							    default:
								  // If we encounter a value that's not recognized,
								  // do not show a button for that one.
								  continue;
								  
						      }
						      aElem.id = 'payment_button_' + i;
						      var linkParams = "'payment_button_" + i + "','" + cn.getAttribute('method') + "'";
						      aElem.setAttribute('href','javascript:Hsa.form.enablePaymentButton(' + linkParams + ');');
						      var imgElem = document.createElement('IMG');
						      imgElem.src = '/img/paymentbutton_' + buttonName + '.png';
						      imgElem.alt = cn.getAttribute('alt') || cn.getAttribute('method');
						      /*
						      buttonElem.name = 'paymentMethod_IGNORETHISFIELD';
						      buttonElem.value = cn.getAttribute('method');
						      */
						      //aElem.onclick = function() { this.parentNode.firstChild.value = this.value; buttonElem.form.submit(); return false; };
						      //aElem.onclick = function() { ; };
						      aElem.appendChild(imgElem)
						      epo.appendChild(aElem);
						}
					}
			}

		}; // var elems

		var name__type = xmlElement.nodeName + '__';
		if (xmlElement.getAttribute('type') != null)
			name__type += xmlElement.getAttribute('type');

		switch (name__type) {
			case 'legend__':
				break;
			case 'field__text':
				elems.field__text(parentElem, xmlElement, currentDepth);
				break;
			case 'field__password':
				elems.field__password(parentElem, xmlElement, currentDepth);
				break;
			case 'field__telnum':
				elems.field__telnum(parentElem, xmlElement, currentDepth);
				break;
			case 'field__select':
				elems.field__select(parentElem, xmlElement, currentDepth);
				break;
			case 'field__buttons':
				elems.field__buttons(parentElem, xmlElement, currentDepth);
				break;
			case 'field__textarea':
				elems.field__textarea(parentElem, xmlElement, currentDepth);
				break;
			case 'field__radio':
				elems.field__radio(parentElem, xmlElement, currentDepth, formObject);
				break;
			case 'field__hidden':
				elems.field__hidden(parentElem, xmlElement, currentDepth);
				break;
			case 'field__action':
				elems.field__action(parentElem, xmlElement, currentDepth);
				break;
			case 'field__pvm':
				elems.field__action(parentElem, xmlElement, currentDepth);
				break;
			case 'field__checkbox':
				elems.field__checkbox(parentElem, xmlElement, currentDepth);
				break;
			case 'field__giftOrderCheckbox':
			    elems.field__checkbox(parentElem, xmlElement, currentDepth);
			    jQuery('#Lahjatilaus').click(function() { Hsa.form.toggleGiftOrder(); });
				break;
			case 'field__captcha':
				elems.field__captcha(parentElem, xmlElement, currentDepth);
				break;
			case 'notetext__':
				elems.notetext__(parentElem, xmlElement, currentDepth);
				break;
			case 'text__':
				elems.text__(parentElem, xmlElement, currentDepth);
				break;
			case 'field__calendar':
				elems.field__calendar(parentElem, xmlElement, currentDepth, formObject);
				break;
			case 'field__duration':
				elems.field__duration(parentElem, xmlElement, currentDepth);
				break;
			case 'field__customerInfo':
				elems.field__customerInfo(parentElem, xmlElement, currentDepth);
				break;
			case 'field__subscriptionInfo':
				elems.field__subscriptionInfo(parentElem, xmlElement, currentDepth);
				break;
			case 'field__selectProduct':
				elems.field__selectProduct(parentElem, xmlElement, currentDepth);
				break;
			case 'field__paymentMethods':
				elems.field__paymentMethods(parentElem, xmlElement, currentDepth);
				break;
			default:
				alert('unknown element name/type: ' + name__type);
		};
	},


	_elementCreatorForTextset: function (parentElem, xmlElement, currentDepth, formObject) {
		if (xmlElement.nodeName == '#text')
			return;
		var elems = {
			text__: function (parentElem, xmlElement, currentDepth) {
				this._text_internal(parentElem, xmlElement, 100);
			},
			_text_internal: function (parentElem, xmlElement, currentDepth) {
				var childNodes = xmlElement.childNodes;
				if (childNodes && childNodes.length>0) {
					for (var i=0; i <= childNodes.length-1; i++) {
						var curChild = xmlElement.childNodes[i];
						// 1=element, 3=text
                        			if ( curChild.nodeType == 1 ) {
							var newNode = document.createElement(curChild.nodeName);
							parentElem.appendChild(newNode);
							var attributes = curChild.attributes;
							for (var j=0; j <= attributes.length-1; j++) {
								newNode.setAttribute(attributes[j].nodeName, attributes[j].nodeValue);
							}
							this._text_internal(parentElem.lastChild, curChild, currentDepth+1);
						} else if (curChild.nodeType == 3) {
							parentElem.appendChild(document.createTextNode(curChild.nodeValue));
						}
					}
				}
			}
		};

		var name__type = xmlElement.nodeName + '__';
		if (xmlElement.getAttribute('type') != null)
			name__type += xmlElement.getAttribute('type');

		switch (name__type) {
			case 'legend__':
				break;
			case 'text__':
				elems.text__(parentElem, xmlElement, currentDepth);
				break;
			default:
				alert('unknown element name/type to textset: ' + name__type);
		}
	},

	submitButton: function (but) {
		if (but.hsaClicked)
			return false;
		but.hsaClicked = true;
		but.form.submit();
		return false;
	},

	abortButton: function (but) {
		if (but.hsaClicked)
			return false;

		if (confirm("Keskeytetäänkö tallentamatta?")) {
			var formObj = but.form;
			if (!formObj)
				return false; // failed to abort
			but.hsaClicked = true;
			formObj.ajaxApiMethodName = 'abort';
			Hsa.form.submitForm(formObj);
			return false;
		}
	},

	backButton: function (but) {
		if (but.hsaClicked)
			return false;

		but.hsaClicked = true;

		if (!but.form)
			return false;

		var phase = this.getPhaseObj(but.form);
		if (!phase)
			return false;
		
		var definedPhase = jQuery(but).data('back-to-phase');
		if (definedPhase) {
			phase = definedPhase;
		} else {
			phase = phase-2; // Yes, really 2.
		}
		
		this.setPhaseObj(but.form, phase);
		Hsa.form.submitForm(but.form);
		return false;
	},

	charCount: function (target) {
			var charsr = target.hsaMaxLength - target.value.length;
			target.hsaUpdateMaxTextLengthTo.innerHTML = charsr + ' merkki' + (charsr != 1 && charsr != -1 ? 'ä' : '') + ' jäljellä';

			if (charsr<0 && !target.hsaAlertedMaxLength) {
				target.hsaAlertedMaxLength = true;
				alert('Tekstin maksimipituus ylittyi.');
			}
			if (charsr>=0)
				target.hsaAlertedMaxLength = false;

	},

	openAddressField: null,

    

//    matchAddressWithPostalCode: function (event, fields, currentErrorMessage) {
    matchAddressWithPostalCode: function (fields) {

        var inputs = fields.split(",");

        var input1Id = jQuery.trim(inputs[0]);
        var input2Id = jQuery.trim(inputs[1]);

        var input1 = jQuery("#"+input1Id);
        var input2 = jQuery("#"+input2Id);

        var input1val = jQuery(input1).val();
        var input2val = jQuery(input2).val();

        var td1 = jQuery(input1).parent();
        var td2 = jQuery(input2).parent();

        var tr1 = jQuery(td1).parent();
        var tr2 = jQuery(td2).parent();

        if( input1val && input2val ){


            jQuery.ajax({
                url: "/hsapi/osoite-postinumero-match.xml",
                data: { field1:input1val, field2:input2val },
                cache: false,
                success: function(responseData){

                    var input1errorMessage = jQuery(responseData).find("response errormsg[forField='1']").text();
                    var input2errorMessage = jQuery(responseData).find("response errormsg[forField='2']").text();

                    var input1ErrorMessageElement = jQuery(input1).next("span.fieldError")[0];
                    var input2ErrorMessageElement = jQuery(input2).next("span.fieldError")[0];

                    if( input1errorMessage ){
                        if( input1ErrorMessageElement ){
                            jQuery(input1ErrorMessageElement).text(input1errorMessage);
                        } else {
                            jQuery(td1).append('<span class="fieldError">' + input1errorMessage + '</span>');
                            jQuery(tr1).addClass('error');
                        }
                    } else {
                        if(input1ErrorMessageElement){
                            jQuery(input1ErrorMessageElement).remove();
                            jQuery(tr1).removeClass('error');
                        }
                    }

                    if( input2errorMessage ){
                        if( input2ErrorMessageElement ){
                            jQuery(input2ErrorMessageElement).text(input2errorMessage);
                        } else {
                            jQuery(td2).append('<span class="fieldError">' + input2errorMessage + '</span>');
                            jQuery(tr2).addClass('error');
                        }
                    } else {
                        if(input2ErrorMessageElement){
                            jQuery(input2ErrorMessageElement).remove();
                            jQuery(tr2).removeClass('error');
                        }
                    }



                }
            });
        }
    },
        
    toggleGiftOrder: function() {
        if (jQuery('#Lahjatilaus').is(':checked')) {
            var $giftOrder = jQuery('.giftOrder').removeClass('hiddenByDefault');
            $giftOrder.prev().removeClass('hiddenByDefault');
            $giftOrder.prev().prev('h2').removeClass('hiddenByDefault');
            var altContent = jQuery('#header-order')[0].altContent;
            jQuery('#header-order em').text(altContent);
        } else {
            var $giftOrder = jQuery('.giftOrder').addClass('hiddenByDefault');
            $giftOrder.prev().addClass('hiddenByDefault');
            $giftOrder.prev().prev('h2').addClass('hiddenByDefault');
            var origContent = jQuery('#header-order')[0].origContent;
            jQuery('#header-order em').text(origContent);
        }
    },
    
    enablePaymentButton: function(clickedElement, methodName) {
        jQuery('.buttonPayment').removeClass('buttonPaymentActive');
        jQuery('#'+clickedElement).addClass('buttonPaymentActive');
        
        jQuery('#input_paymentMethod').val(methodName);
        
        if (methodName == 'lasku') {
            jQuery('#paymentApproveButton').val('Hyväksy');
        } else {
            jQuery('#paymentApproveButton').val('Hyväksy ja maksa');
        }
        jQuery('#paymentApproveButton').removeClass().addClass('button buttonStrong buttonLarge').removeAttr('disabled');
    }




};

