if(!ch){
	var ch = {};
}
if(!ch.exmachina){
	ch.exmachina = {};
}
if(!ch.exmachina.bravofly){
	ch.exmachina.bravofly = {};
}
/**
 * @constructor
 * @param {Object} ctorArgs
 */
ch.exmachina.bravofly.GeographicInput = function(/* object */ctorArgs){

	var _timestamp = (new Date()).getTime(),
		_template = this.template.replace(/\${GeographicInputId}/g, _timestamp),
		self = this
	;
    this.aspect = ctorArgs.aspect || "default";
    if(this.aspect == "overlapped"){
        _template = this.overlapTemplate.replace(/\${GeographicInputId}/g, _timestamp);
    }
	this.nationPrompt = ctorArgs.nationPrompt || "";
	this.areaPrompt = ctorArgs.areaPrompt || "";
	this.containerNode = ctorArgs.containerNode,
	this.domNode = document.createElement("div");
	this.domNode.style.textAlign = "center";
	this.domNode.style.margin = "auto";
	this.domNode.style.width = "100%";

	this.containerNode.appendChild(this.domNode);
	this.onClose = ctorArgs.onClose || this.onClose;
	this.domNode.innerHTML = _template;
	this.tNode = $("TNode_" + _timestamp);
	this.tNode.style.textAlign = "center";
	this.tNode.writeAttribute("id", null);
	this.searchLanguage = ctorArgs.searchLanguage || "EN";
    this.readOnly = !!ctorArgs.readOnly;
    this.nationCompleteUrl = ctorArgs.nationCompleteUrl;
    this.datasource = ctorArgs.datasource || this.datasource;
    this.onChangeNation = ctorArgs.onChangeNation || this.onChangeNation;
    this.onChangeArea = ctorArgs.onChangeArea || this.onChangeArea;
    this.pGroup = ctorArgs.pGroup;
    this.selectUrl = ctorArgs.selectUrl || this.selectUrl;
    this.cibavisionFields = !!ctorArgs.nationUnderlined;
    this.onFirstSelectionChange = ctorArgs.onFirstSelectionChange;
    this.asynchAreaLoad = ctorArgs.asynchAreaLoad === false ? false : true;
    this.areaDataKey = ctorArgs.areaDataKey;
    this.selectContentType = ctorArgs.selectContentType || "";
    this._firstOption = ctorArgs.firstOption;
    this.selectClass = ctorArgs.selectClass || ch.exmachina.bravofly.Select;

//	this.cleanNode = $("Clean_" + _timestamp);
//    if(this.cleanNode){
//        this.cleanNode.writeAttribute("id", null);
//    }

    var fieldWidth = "190px",
        fieldAreaWidth = "170px",
        areaFieldDisplay = "inline",
        afterFreeze = function(){},
        onLoadArea = function(){
            var list = this.listData,
                nations = [];
            for (var i = 0; i < list.size(); i++) {
                if (list[i].description && nations.indexOf(list[i].description) == -1) {
                    nations.push(list[i].description);
                }
            }
            this.enclosingObject.nationField.fieldNode.value = nations.join(" - ");
        },
        onCompleteArea = function(){},
        onCleanArea = function(){}
    ;
    if(this.aspect == "overlapped"){
        fieldWidth = "370px";
        fieldAreaWidth = "370px";
        areaFieldDisplay = "none";
        onLoadArea = function(){
        	if(this.autoLoad){
        		this.autoLoad = false;
        		return;
        	}
        	if(self.aspect === "overlapped" && this.listData && this.listData.length === 1) {
        		return;
        	}
            this.showList();
            this.highlightOptionIndex(0);
            this.selectFieldNode.focus();
        };
        onCompleteArea = function(){

        };
        onCleanArea = function(){
            this.nationField.domNode.style.display = "block";
            this.areaField.domNode.className = "";
            this.areaField.domNode.style.height = this.areaField.selectFieldNode.style.height = "0";
            this.areaField.selectFieldNode.className = "";
            this.areaField.listButton.style.display = "none";
            this.areaField.clearButton.style.display = "none";
            this.nationField.clean();
            this.nationField.unfreeze();
            this.nationField.onClose();
        };
        afterFreeze = function(){
            this.nationField.domNode.style.display = "none";
            this.areaField.domNode.className = "ta_rich_field";
            this.areaField.domNode.style.height = this.areaField.selectFieldNode.style.height = "17px";
            this.areaField.selectFieldNode.className = "ta_rich_field fixed";
            this.areaField.listButton.style.display = areaFieldDisplay;
            this.areaField.clearButton.style.display = "block";
            //funziona per il Chrome e Safari
			this.areaField.domNode.style.display = "block";

            this.onFreeze();
        };
    }else if(this.aspect == "doubleSelect"){
        fieldWidth = "160px";
        fieldAreaWidth = "190px";
    }
//	this.nationFieldNode = $("Nation_" + _timestamp);
//	this.nationFieldNode.writeAttribute("id", null);

	// start callback functions
	this.onFreeze = ctorArgs.onFreeze || this.onFreeze;
	this.onUnfreeze = ctorArgs.onUnfreeze || this.onUnfreeze;
	// end callback functions
    if(this.aspect != "doubleSelect"){
        this.nationField = new ch.exmachina.bravofly.RichField({
            pNode: "Nation_" + _timestamp,
            autocompleteURL: this.nationCompleteUrl,
            promptText: this.nationPrompt,
            searchLanguage: this.searchLanguage,
            continentCode: ctorArgs.continentCode,
            defaultValue: ctorArgs.defaultNation,
            readOnly: false,
            onFreeze: function(){
                if(self.datasource == "net"){
                    self.areaField.loadData({
                        key: this.getStoredId(),
                        isoCode: "true",
                        language: self.areaField.searchLanguage
                    });
                }
                self.areaField.enable();
                self.onFreeze();
                afterFreeze.call(self);
            },
            onUnfreeze: function(){
                if(self.readOnly){ return; }
                self.areaField.disable();
                self.onUnfreeze();
            },
            onClose: function(){
                if(!self.readOnly){ this.clean(); }
                self.onClose();
                self.pGroup.onRemoveChild();
            }
        });
        if(this.cibavisionFields){
        	var s = this.nationField.fieldNode.style;
        	s.border = "none";
        	s.borderBottom = "1px solid #BACDDB";
        	s.background = "none";
        	s.paddingBottom = "3px";
        }
    }else{
//        var targetNode = document.createElement("div");
//        this.domNode.appendChild(targetNode);
        this.nationField = new this.selectClass({
            nodeId: "Nation_" + _timestamp,
            searchLanguage: this.searchLanguage,
            width: parseInt(fieldWidth),
            dataKey: this.dataKey,
            pGroup: this,
            enclosingObject: this,
            promptText: this.promptText,
            firstOption: this._firstOption,
            onLoad: function(){ this.enable(); },
            onFirstChange: this.onFirstSelectionChange,
            onChange: this.onChangeNation,
            onClean: function(){
                var pGroup = self.pGroup,
                    fields = pGroup.fields
                ;
                if(!pGroup.disabled && pGroup.fields.length > pGroup.minFields){
                    var idx = fields.indexOf(self);
                    pGroup.removeField(idx);

                    pGroup.onRemoveChild();
                    pGroup.setCloserButtons();
                }
                //if(fields.length < pGroup.maxFields){
                   // pGroup.enableAddNode();
                //}
            },
            url: this.selectUrl
        });
    }
	var ns = this.nationField.fieldNode.style;
	ns.width = fieldWidth;
	ns.padding = ns.margin = "0";
	ns.height = "17px";
	if(this.nationField.clearButton){
		this.nationField.clearButton.style.display = "block";
	}
	this.nationField.indicatorNode && (this.nationField.indicatorNode.style.width = fieldWidth);
	this.areaField = new this.selectClass({
		nodeId: "areaTarget_" + _timestamp,
		searchLanguage: this.searchLanguage,
        width: parseInt(fieldAreaWidth),
        enclosingObject: this,
        contentType: this.selectContentType,
		promptText: this.areaPrompt,
        onLoad: onLoadArea,
        dataKey: this.areaDataKey,// "availableDepartureGeoArea",
        onChange: this.onChangeArea,
        asynchLoad: this.asynchAreaLoad,
        firstOption: this.cibavisionFields ? { key: "", value: this._firstOption } : null,
        onFirstChange: this.onFirstSelectionChange,
        onComplete: function(){ onCompleteArea.call(self); },
        onClean: function(){ onCleanArea.call(self); },
		url: this.selectUrl//ctorArgs.geoCompleteURL
	});

    if(this.aspect == "overlapped"){
        this.areaField.domNode.style.height = "0";
        this.areaField.domNode.className = "";
        this.areaField.selectFieldNode.style.height = "0";
        this.areaField.domNode.style.marginLeft = "8px";
        if(Prototype.Browser.WebKit){
            // safari hack:
            this.areaField.domNode.style.display = "none";
        }
    }
    this.areaField.listButton.style.display = areaFieldDisplay;

    if(ctorArgs.defaultNation){
        this.areaField.setValue(ctorArgs.defaultNation);
        this.areaField.onFirstChange = function(){
            this.firstOption = false;
            this.listData.shift();
            this.selectedIndex--;
            this.createList();
        };

        this.nationField.storedId = "ITA";
        this.nationField.freeze();
    }

	this.tNode.observe("click", this.click.bindAsEventListener(this));
};

ch.exmachina.bravofly.GeographicInput.prototype = {
	// nodes
	/**
	 * Nodo DOM contenente la table che fa da wrapper
	 * @type {Node}
	 */
	tNode: null,
	/**
	 * Nodo DOM su cui e' basato questo oggetto
	 * @type {Node}
	 */
	domNode: null,
	/**
	 * da rimuovere, inutilizzata adesso
	 */
    cleanNode: null,
	/**
	 * Rich field contenente la nazione
	 * @type {ch.exmachina.bravofly.RichField}
	 */
	nationField: null,
	/**
	 * Campo contenente l'area geografica: il tipo di questo oggetto viene definito a runtime in base al contenuto
	 * di ch.exmachina.bravofly.GeographicInput.selectClass, se presente. In caso contrario la classe utilizzata sara'
	 * ch.exmachina.bravofly.Select
	 * @type {Object}
	 */
	areaField: null,
	/**
	 * Lingua in cui verranno effettuate le ricerche sugli autocompleter, viene passato ai costruttori dei singoli
	 * fields, quindi ogni modifica successiva a questa proprieta' non avra' effetto sui singoli autocompleters
	 * @type {String}
	 * @default EN
	 */
	searchLanguage: "EN",
	/**
	 * Testo da mostrare inizialmente nel campo nazione, equivalente al placeholder di html5. Non puo' essere modificato
	 * in seguito al costruttore, agendo su questa proprieta', poiche' viene passata al singolo oggetto field
	 * @type {String}
	 * @default ""
	 */
	nationPrompt: "",
	/**
	 * Testo da mostrare inizialmente nel campo area
	 * @type {String}
	 * @default ""
	 */
	areaPrompt: "",
	/**
	 * Determina l'aspetto di questo oggetti. Una tra doubleSelect, overlapped o default
	 * @type {String}
	 * @default ""
	 */
    aspect: "",
	/**
	 * Se valorizzato come "net", questo campo viene riempito con dati presi da una chiamata xhr dopo la costruzione
	 * @type {String}
	 * @default net
	 */
    datasource: "net",
	/**
	 * Gruppo di appartenenza di questo campo. Utilizzato per notificare gli eventi al contenitore
	 * @type {ch.exmachina.bravofly.GeographicGroup}
	 * @default null
	 */
    pGroup: null,
	/**
	 * Prima opzione da passare alle select, da mostrare assieme ai dati remoti
	 * @type {Object}
	 * @default null
	 */
    _firstOption: null,
	/**
	 * Url da passare alla select per recuperare i dati
	 * @type {String}
	 * @default ""
	 */
    selectUrl: "",
	/**
	 * Determina l'aspetto di questo oggetto in base ad altre condizioni; hack quick and dirty per gestire un caso
	 * particolare
	 * @type {boolean}
	 * @default false
	 */
    cibavisionFields: false,
	/**
	 * Hook eseguito quando viene cambiato il valore del campo nazione. Puo' essere passato dall'esterno, in fase di
	 * costruzione
	 * @type {Function}
	 * @default function(){}
	 */
    onChangeNation: function(){},
	/**
	 * Hook eseguito quando viene modificato il valore del campo area. Passabile dall'esterno in fase di costruzione
	 * @type {Function}
	 * @default function(){}
	 */
    onChangeArea: function(){},
	/**
	 * Determina se la connessione per recuperare il contenuto del campo area dovra' essere asincrona o meno. Usata
	 * in pricesearch per non introdurre complessita' nell'applicazione e per implementare velocemente alcuni vincoli
	 * @type {boolean}
	 * @default true
	 */
    asynchAreaLoad: true,
	/**
	 * Chiave da utilizzare nella classe che costruisce l'oggetto Select
	 * @type {String}
	 * @default ""
	 */
    areaDataKey: "",
	/**
	 * Costruttore che sara' usato per istanziare la Select appartenente a questo GeographicInput.
	 * @type {Function}
	 * @default null
	 */
    selectClass: null,
	/**
	 * Template principale di questo oggetto
	 * @type {String}
	 */
	template: '<div style="width:400px;margin:auto;text-align:center"><table id="TNode_${GeographicInputId}" style="width:400px;text-align:center;margin:auto;border-collapse:collapse;padding:0;margin:0"><tbody>' +
		'<tr><td style="vertical-align:top" id="Nation_${GeographicInputId}"></td>' +
		'<td style="vertical-align:top" id="areaTarget_${GeographicInputId}"></td></tr>' +
		'</tbody></table></div>',
	/**
	 * Template della parte sovrapposta
	 * @type {String}
	 */
	overlapTemplate: '<div id="TNode_${GeographicInputId}" style="height:20px;width:400px;margin:5px auto;text-align:center">' +
		'<div id="Nation_${GeographicInputId}"></div>' +
		'<div style="text-align:center;"><div style="margin:auto;text-align:left" id="areaTarget_${GeographicInputId}"></div></div>' +
		'</div>',
	// hooks
	/**
	 * Aggancio per la onChange
	 * @type {Function}
	 * @default function(){}
	 */
	onChange: function(){
	},
	/**
	 * Aggancio per la onFreeze
	 * @type {Function}
	 * @default function(){}
	 */
	onFreeze: function(){
	},
	/**
	 * Aggancio per la onUnfreeze
	 * @type {Function}
	 * @default function(){}
	 */
	onUnfreeze: function(){
	},
	/**
	 * Aggancio per la onClose
	 * @type {Function}
	 * @default function(){}
	 */
	onClose: function(){
	},
	// end hooks
	/**
	 * Restituisce il valore del campo nazione appartenente a questo GeographicInput
	 * @return {String}
	 */
	getNationValue: function(){
		return this.nationField.getValue();
	},
	/**
	 * Restituisce il valore di questo oggetto, che coincide con quello dell'area geografica selezionata
	 * @return {String}
	 */
	getValue: function(){
		return this.areaField.getValue();
	},
	/**
	 * Disabilita questo GeographicInput
	 */
	disable: function(){
		this.disabled = true;
	},
	/**
	 * Abilita questo GeographicInput
	 */
	enable: function(){
		this.disabled = false;
	},
	/**
	 * Restituisce il valore di dirty per questo campo. E' false finche' l'utente non modifica il valore iniziale.
	 * Coincide col valore di dirty del RichField della nazione
	 * @return {boolean}
	 */
	isDirty: function(){
		return this.nationField.dirty;
	},
	/**
	 * Restituisce true se il nationField dell'oggetto corrente e' disabilitato
	 * @return {boolean}
	 */
	isDisabled: function(){
		return this.nationField.disabled;
	},
	/**
	 * Ritorna true quando il campo corrente e' completo, che e' equivalente ad avere l'area geografica completata
	 * @return {boolean}
	 */
	isFreezed: function(){
//		return this.nationField.isFreezed();
		return this.areaField.isValid();
	},
	/**
	 * Restituisce lo stato di validita' di questo campo, calcolato in base alla conformazione (aspect) dell'oggetto
	 * stesso
	 * @return {boolean}
	 */
    isValid: function(){
        return this.aspect != "doubleSelect" ? this.isFreezed() : this.areaField.isValid();
    },
	/**
	 * Gestore dell'evento onclick
	 * @param {Event} evt
	 */
	click: function(evt){
		if(this.disabled){ return; }
		var target = evt.element();
		if(target !== this.domNode){ return; }
		this.onChange.call(this);
	},
	/**
	 * Pulisce il campo corrente, disabilitando contemporaneamente il campo contenente l'area
	 */
	clean: function(){
        if(this.readOnly){ return; }
		this.areaField.disable();
	},
	/**
	 * Distrugge il campo corrente (attenzione, solo DOM, gli eventi non sono sganciati)
	 */
	destroy: function(){
		this.domNode.parentNode.removeChild(this.domNode);
	},
	/**
	 * Restituisce la stringa contenente il nome completo di questa classe, aggiungere informazioni utili in caso
	 * di debug
	 */
	toString: function(){
		return "[ch.exmachina.bravofly.GeographicInput]" ;
	}
};

