
	//*********************************** Lang manager API class *************************************
    var CLangmgrAPI = function(){
        //buttons array
        this.instances = new Array(); //[0] => name ; [1] => object
    }

    CLangmgrAPI.prototype.get_instance = function(name)
    {
        for(var i = 0; i < this.instances.length; i++){
            if(this.instances[i][0] == name) return this.instances[i][1];
        }
        return null;
    }

    CLangmgrAPI.prototype.add_instance = function(name, instance)
    {
        this.instances[this.instances.length] = new Array(name, instance);
    }

    //creating api object
    var LangmgrAPI = new CLangmgrAPI();


    
    
    //*********************************** Events implementation for attached to tabbed control*********************************************
    function lang_tabctrl_on_before_change(tabctrl_instance){
    	lang_instance = tabctrl_instance.get_data(); 
    	//updating lang controls
    	lang_instance.update_lang_ctrls(lang_instance.get_active_lang_code());
    }
    
    function lang_tabctrl_on_after_change(tabctrl_instance){    	
    	lang_instance = tabctrl_instance.get_data(); 
    	//setting new lang code
    	lang_instance.set_active_lang(tabctrl_instance.get_active_btn_name());
    	//updating user controls
    	lang_instance.update_user_ctrls(lang_instance.get_active_lang_code());
    	//updating enabled checkbox state
		lang_instance.update_enable_checkbox_state();	
		//updating enabled checkbox visibility
		lang_instance.update_enable_checkbox_visibility();
		//updating controls visibility
		lang_instance.update_ctrls_visibility();	 	
    }

    function lang_on_form_submit(){
    	var instance_name = this.elements["lang_instance_name"].value
    	instance = LangmgrAPI.get_instance(instance_name);
    	return instance.submit();
    }
    
    function lang_on_enable_lang(instance_name){
    	instance = LangmgrAPI.get_instance(instance_name);
    	enable_checkbox = document.getElementById(instance.lang_prefix + 'enablechk_' + instance_name);
    	if(!enable_checkbox) return;
    	//enabling language
    	langs = instance.get_langs();
    	for(var i = 0; i < langs.length; i++){
    		if(langs[i][0] == instance.get_active_lang_code())
    			langs[i][2] = (enable_checkbox.checked);
    	}
    	instance.update_ctrls_visibility();
    }
    
    
    //*********************************** Various functions *********************************************
    
    
    function lang_set_fckeditor_value(instance_name, value){
    	try {
			user_ctrl = FCKeditorAPI.GetInstance(instance_name);   
			user_ctrl.SetHTML(value,false); 							
    	} catch(e) {
    		//retrying because FCKeditorAPI is not ready
    		setTimeout('lang_set_fckeditor_value("' + instance_name + '","' + value + '");', 500);
    	}	
    }
    
    function lang_fire_fckeditor_events(instance_name){
    	try {
    		user_ctrl = FCKeditorAPI.GetInstance(instance_name); 
			if(FCKeditor_OnSelectionChange) FCKeditor_OnSelectionChange(user_ctrl);
			if(FCKeditor_OnAfterSetHTML) FCKeditor_OnAfterSetHTML(user_ctrl);							
    	} catch(e) {
    		//retrying because FCKeditorAPI is not ready
    		setTimeout('lang_fire_fckeditor_events("' + instance_name + '");', 500);
    	}	
    }
    

    //*********************************** Language manager API class *************************************    
    
	var CLangmgr = function(instance_name){
		//instance_name
        this.instance_name = instance_name;
        //languages array
        this.langs = new Array();
        //active lang
        this.active_lang_code = '';
	 	//form id
	 	this.form_id = '';
	 	//form onsubmit
	 	this.form_onsubmit = null;
	 	//tab container id
	 	this.tab_container_id = '';
	 	//ctrl container id
	 	this.ctrls_container_id = '';
        //controls array
        this.ctrls = new Array();
        //lang prefix for all controls
        this.lang_prefix = 'lang_';
        //lang tag
        this.lang_tag = '';
        //lang manager state
        this.state = 0;		//0 if not loaded; 1 if loaded
        //tabbed control
        this.tabctrl = new CTabctrl(this.lang_prefix + 'tab_' + this.instance_name,this.lang_prefix + 'btn_' + this.instance_name);
        this.tabctrl.set_data(this);
        this.tabctrl.on_before_change = lang_tabctrl_on_before_change;
        this.tabctrl.on_after_change = lang_tabctrl_on_after_change;
        //adding instance to API array
        LangmgrAPI.add_instance(instance_name, this);
    }
    
    //set prefix for lang objects
    CLangmgr.prototype.set_lang_prefix = function(prefix)
    {
        this.lang_prefix = prefix;
    }
    
    //set lang tag to use in post operations
    CLangmgr.prototype.set_lang_tag = function(tag)
    {
        this.lang_tag = tag;
    }
    
    //set id of the form
    CLangmgr.prototype.set_form_id = function(id)
    {
        this.form_id = id;
    }
    
    //set id of the div tab control container
    CLangmgr.prototype.set_tab_container_id = function(id)
    {
        this.tab_container_id = id;
    }
    
    //set id of the div form container
    CLangmgr.prototype.set_ctrls_container_id = function(id)
    {
        this.ctrls_container_id = id;
    }
    
    //adds a language 
    CLangmgr.prototype.add_lang = function(code, name, enabled)
    {
    	//setting default value for active
    	var enabled = (enabled == null) ? false : enabled;
    	//adding language
    	this.langs[this.langs.length] = new Array(code, name, enabled);
    	//adding button to tabcontrol
        this.tabctrl.add_button(code, code, code + ' (' + name + ')', code, '')
    }
    
    //gets a language
    CLangmgr.prototype.get_lang = function(code)
    {
        for(var i = 0; i < this.langs.length; i++){
            if(code == this.langs[i][0]) return this.langs[i];
        }
        return null;
    }
    
    //gets language array
    CLangmgr.prototype.get_langs = function()
    {
        return this.langs;
    }    
    
    
    //sets active language
    CLangmgr.prototype.set_active_lang = function(code)
    { 
    	for(var i = 0; i < this.langs.length; i++)
    		if(this.langs[i][0] == code){
    			//setting active language and button
    			this.active_lang_code = code;
        		this.tabctrl.set_active_btn(code);        		
        		if(this.state == 1){
        			//updating user controls
        			this.update_user_ctrls(code);
	        		//updating enabled checkbox state
	    			this.update_enable_checkbox_state();	
	    			//updating enabled checkbox visibility
	    			this.update_enable_checkbox_visibility();
	    			//updating controls visibility
	    			this.update_ctrls_visibility();	
        		}
    		}

    }
    
    //gets active language
    CLangmgr.prototype.get_active_lang = function()
    {
        return this.get_lang(this.active_lang_code);
    }
    
    //gets code of the active language
    CLangmgr.prototype.get_active_lang_code = function()
    {
        return this.active_lang_code;
    }
    
    //registers a user control
    CLangmgr.prototype.register_ctrl = function(id, type, required, value, validate_proc)
    {
        return this.ctrls[this.ctrls.length] = new Array(id, type, required, value, validate_proc);
    }
    
    //gets value for a lang control
    CLangmgr.prototype._get_lang_ctrl_value = function(id, code)
    {
    	open_tag = this._get_open_tag(code);
    	close_tag = this._get_close_tag(code);
    	//getting lang control and its value
		lang_ctrl = document.getElementById(this.lang_prefix + 'ctrl_' + id); 
		lang_ctrl_value = lang_ctrl.value;
		//getting start and end index of the value for the current code and control
		start = lang_ctrl_value.indexOf(open_tag) + open_tag.length;  
		end = lang_ctrl_value.indexOf(close_tag) - 1;      		
		//return lang value for code
		return lang_ctrl_value.substring(start, end + 1);
    }
    
    //gets value for a user control
    CLangmgr.prototype._get_user_ctrl_value = function(id)
    {
    	for(var i = 0; i < this.ctrls.length; i++){    		
    		var ctrl = this.ctrls[i];
			if(ctrl[0] == id){
				var value = '';
				switch(ctrl[1]){ //type
					case 'text'			:	
					{
						user_ctrl = document.getElementById(ctrl[0]);
						value = user_ctrl.value;
						break;
					}
					case 'textarea'		:
					{
						user_ctrl = document.getElementById(ctrl[0]);
						value = user_ctrl.value;
						break;
					}
					case 'fckeditor'	:
					{
						user_ctrl = FCKeditorAPI.GetInstance(ctrl[0]);     
						value = user_ctrl.GetXHTML('');
						break;
					}
				}				
				return value;
			}
    	}	    
    	return null;
    }
    
	//sets value for a user control
    CLangmgr.prototype._set_user_ctrl_value = function(id, value)
    {
    	for(var i = 0; i < this.ctrls.length; i++){    		
			if(this.ctrls[i][0] == id){
				switch(this.ctrls[i][1]){ //type
					case 'text'			:	
					{
						user_ctrl = document.getElementById(id);
						user_ctrl.value = value;
						break;
					}
					case 'textarea'		:
					{
						user_ctrl = document.getElementById(id);
						user_ctrl.value = value;
						break;
					}
					case 'fckeditor'	:
					{
						lang_set_fckeditor_value(id,value);
					}
				}				
			}
    	}	    
    }
    
    //fires events for a user control
    CLangmgr.prototype._fire_user_ctrl_events = function(id){
    	for(var i = 0; i < this.ctrls.length; i++){    		
			if(this.ctrls[i][0] == id){
				switch(this.ctrls[i][1]){ //type
					case 'text'			:	
					{
						user_ctrl = document.getElementById(id);
						if(user_ctrl.onkeydown) user_ctrl.onkeydown();
						if(user_ctrl.onkeypress) user_ctrl.onkeypress();
						if(user_ctrl.onkeyup) user_ctrl.onkeyup();
						break;
						
					}
					case 'textarea'		:
					{
						user_ctrl = document.getElementById(id);
						if(user_ctrl.onkeydown) user_ctrl.onkeydown();
						if(user_ctrl.onkeypress) user_ctrl.onkeypress();
						if(user_ctrl.onkeyup) user_ctrl.onkeyup();
						break;
					}
					case 'fckeditor'	:
					{
						lang_fire_fckeditor_events(id);          
					}
				}				
			}
    	}	    	
    
    }
    
    //gets open tag for language values
    CLangmgr.prototype._get_open_tag = function(code){
  		return '<' + this.lang_tag.replace('%LG', code) + '>';		
    }
    
    //gets close tag for language values
    CLangmgr.prototype._get_close_tag = function(code){
  		return '</' + this.lang_tag.replace('%LG', code) + '>';		
    }
    
    //gets a tagged language value
    CLangmgr.prototype._get_tagged_value = function(code, value){
  		return this._get_open_tag(code) + value + this._get_close_tag(code);		
    }
    
    //enabled languages from control value   
    CLangmgr.prototype._enable_langs_from_ctrls_values = function(){    
    	for(var i = 0; i < this.langs.length; i++){
    		if(this.langs[i][2]) continue;
    		var open_tag = this._get_open_tag(this.langs[i][0]);
    		var close_tag = this._get_close_tag(this.langs[i][0]);
    		var enable = false;
    		for(var j = 0; j < this.ctrls.length; j++){
    			var ctrl_value = this.ctrls[j][3];
    			enable = enable || (ctrl_value.indexOf(open_tag) != -1 && ctrl_value.indexOf(close_tag) != -1);				
    		}
    		this.langs[i][2] = enable;
    	}
    		
    }
    
	//updates visibility for the checkbox used for enabling/disabling language   
    CLangmgr.prototype.update_enable_checkbox_visibility = function(){    
    	enable_cont = document.getElementById(this.lang_prefix + 'enablecont_' + this.instance_name);
    	if(!enable_cont) return;
    	if(!this.get_active_lang()){
    		enable_cont.style.display = 'none'; 
    	} else {
    		enable_cont.style.display = '';
    	}
    		
    }
    
    //updates state for the checkbox used for enabling/disabling language
    CLangmgr.prototype.update_enable_checkbox_state = function(){    
    	enable_checkbox = document.getElementById(this.lang_prefix + 'enablechk_' + this.instance_name);
		enable_lgname = document.getElementById(this.lang_prefix + 'enablelgname_' + this.instance_name);    	
    	if(!enable_checkbox || !enable_lgname) return;	
    	if(!this.get_active_lang()){
    		enable_checkbox.checked	= false;
    		return;	
    	}
    	enable_checkbox.checked = this.get_active_lang()[2];
    	enable_lgname.innerHTML = this.get_active_lang()[1];
    }
    
    //updates visibility for user controls
    CLangmgr.prototype.update_ctrls_visibility = function(){
    	ctrls_container = document.getElementById(this.ctrls_container_id);
    	if(!ctrls_container) return;
    	if(!this.get_active_lang()){
    		ctrls_container.style.display = 'none'; 
    		return;
    	}
		if(this.get_active_lang()[2])
			ctrls_container.style.display = '';
		else
			ctrls_container.style.display = 'none';
    }
    
    //Updates lang hidden controls values with user controls values
    CLangmgr.prototype.update_lang_ctrls = function(code){
    	if(this.state == 0) return;
    	//getting open and close tag for this language code
    	open_tag = this._get_open_tag(code);
    	close_tag = this._get_close_tag(code);
  		for(var i = 0; i < this.ctrls.length; i++){    		
  			//getting lang control and its value
    		lang_ctrl = document.getElementById(this.lang_prefix + 'ctrl_' + this.ctrls[i][0]); 
    		lang_ctrl_value = lang_ctrl.value;
    		//getting start and end index of the value for the current code and control
    		start = lang_ctrl_value.indexOf(open_tag) + open_tag.length;  
    		end = lang_ctrl_value.indexOf(close_tag) - 1;      		
    		//updating lang control
    		if(start >= 0 && end >= 0){
    			lang_ctrl.value = lang_ctrl_value.substring(0, start) + this._get_user_ctrl_value(this.ctrls[i][0]) + lang_ctrl_value.substring(end + 1, lang_ctrl_value.length);
    		} else {
				lang_ctrl.value = lang_ctrl.value + open_tag + this._get_user_ctrl_value(this.ctrls[i][0]) + close_tag;			
    		}
    	}		
    }
    
    //Updates user controls values with lang hidden controls values
    CLangmgr.prototype.update_user_ctrls = function(code){
    	if(this.state == 0) return;
    	//getting open and close tag for this language code
    	open_tag = this._get_open_tag(code);
    	close_tag = this._get_close_tag(code);
  		for(var i = 0; i < this.ctrls.length; i++){    		
  			//getting lang control and its value
    		lang_ctrl = document.getElementById(this.lang_prefix + 'ctrl_' + this.ctrls[i][0]); 
    		lang_ctrl_value = lang_ctrl.value;
    		//getting start and end index of the value for the current code and control
    		start = lang_ctrl_value.indexOf(open_tag) + open_tag.length;  
    		end = lang_ctrl_value.indexOf(close_tag) - 1;      		
    		//updating user control
    		if(start >= 0 && end >= 0){
    			this._set_user_ctrl_value(this.ctrls[i][0], lang_ctrl_value.substring(start, end + 1));
    		} else {
    			this._set_user_ctrl_value(this.ctrls[i][0], '');
    		}
    		this._fire_user_ctrl_events(this.ctrls[i][0]);
    	}		
    }
    
    //output language manager
    CLangmgr.prototype.output = function(auto_enable_langs){
    	//setting default value for auto_enable_lang
    	var auto_enable_langs = (auto_enable_langs == null) ? false : auto_enable_langs;
    	//exit if already output
    	if(this.state == 1) return;
    	//enabling languages for wich controls have values
		if(auto_enable_langs)
			this._enable_langs_from_ctrls_values();
    	//getting form element
    	form = document.getElementById(this.form_id);
    	if(!form) return;
   		//creating hidden control that contains instance_name of the current CLangmgr object
   		var ctrl   = document.createElement('input');
		ctrl.type  = 'hidden';
		ctrl.id    = 'lang_instance_name';
		ctrl.value = this.instance_name;
		//adding control to the form
		form.appendChild(ctrl);
    	//creating hidden lang controls
    	for(var i = 0; i < this.ctrls.length; i++){    		
    		var ctrl   = document.createElement('input');
			ctrl.type  = 'hidden';
			ctrl.name  = this.lang_prefix + 'ctrl_' + this.ctrls[i][0];
			ctrl.id    = this.lang_prefix + 'ctrl_' + this.ctrls[i][0];
			var ctrl_value = this.ctrls[i][3];
			//adding languages that are not in value
			for(var j = 0; j < this.langs.length; j++){
				code = this.langs[j][0];
				if(ctrl_value.indexOf(this._get_open_tag(code)) == -1)
					ctrl_value += this._get_tagged_value(code,'');
			}		
			//assignig value
			ctrl.value = ctrl_value;
			//adding control to the form
			form.appendChild(ctrl);
    	}						
    	//setting form on sumbit
    	form = document.getElementById(this.form_id);
    	//backing up old onsumbit
    	if(form.onsubmit){   		
    		this.form_onsubmit = form.onsubmit;   
    	}
    	//setting new onsubmit
    	form.onsubmit = lang_on_form_submit;
    	//creating tab controlrm.onsubmit = lang_submitform;	
    	tab_container = document.getElementById(this.tab_container_id);
        if(!tab_container) return;
    	tab_container.innerHTML = this.tabctrl.get_html(); 
    	tab_container.innerHTML += '<br><div id="' + this.lang_prefix + 'enablecont_' + this.instance_name + '"><input id="' + this.lang_prefix + 'enablechk_' + this.instance_name + '" type="checkbox" border="0" onClick="javascript: lang_on_enable_lang(\'' + this.instance_name + '\');">&nbsp;&nbsp;<b>Attiva la lingua \"<span id="' + this.lang_prefix + 'enablelgname_' + this.instance_name + '"></span>\"</b></div><br>';
    	//updatiung state
		this.state = 1;
    	//updating user controls
    	if(this.active_lang_code){
    		this.update_user_ctrls(this.active_lang_code);			
    	}
    	//updating enabled checkbox state
		this.update_enable_checkbox_state();	
		//updating enabled checkbox visibility
		this.update_enable_checkbox_visibility();
		//updating controls visibility
		this.update_ctrls_visibility();
    }
  
    //prepares controls for submit operations
    CLangmgr.prototype.submit = function(){
    	//checking for required fields
    	if(this.check_required() !== false) return false;
    	//executing old submit
    	if(this.form_onsubmit){
	    	if(!this.form_onsubmit())
	    		return false;  
    	}  
	    //updating lang controls
	    this.update_lang_ctrls(this.active_lang_code);		    
    	//changing controls names	
  		for(var i = 0; i < this.ctrls.length; i++){  
  			//getting user control
  			user_ctrl = document.getElementById(this.ctrls[i][0]); 
  			//changing user control name
  			user_ctrl.name = '';	
  			//getting lang control
    		lang_ctrl = document.getElementById(this.lang_prefix + 'ctrl_' + this.ctrls[i][0]); 
    		//setting new lang control name
    		lang_ctrl.name = this.ctrls[i][0]; 
    		//deleting non-active langs values 
  			for(var j = 0; j < this.langs.length; j++){
  				if(this.langs[j][2]) continue;      
  				open_tag = this._get_open_tag(this.langs[j][0]);
    			close_tag = this._get_close_tag(this.langs[j][0]);	
  				//getting start and end index of the value for the current code and control
  				lang_ctrl_value = lang_ctrl.value;
    			start = lang_ctrl_value.indexOf(open_tag);  
    			end = lang_ctrl_value.indexOf(close_tag) + close_tag.length - 1; 
				//setting value    		
    			lang_ctrl.value = lang_ctrl_value.substring(0, start) + lang_ctrl_value.substring(end + 1, lang_ctrl_value.length)
  			}
    	}	
    	//returning
    	return true;	
    }
    
    
    //check required fields for lang code
    CLangmgr.prototype.check_required_lang = function(code){
    	lang = this.get_lang(code);
    	if(!lang) return false;
    	if(!lang[2]) return false;
    	//updating lang controls
    	this.update_lang_ctrls(this.active_lang_code);
    	//initializing result
    	var result = new Array();
    	//getting required array
    	for(var i = 0; i < this.ctrls.length; i++){  
    		if(this.ctrls[i][2] && !this._get_lang_ctrl_value(this.ctrls[i][0], code))
    			result[result.length] = this.ctrls[i][0];
    	}	
    	//returning result
    	if(result.length == 0) 
    		return false;
    	else
    		return result;
    }
    
    //check required fields for all languages
    CLangmgr.prototype.check_required = function(){
    	//updating lang controls
    	this.update_lang_ctrls(this.active_lang_code);
    	//initializing result
    	var result = new Array();
    	//getting required array
    	for(var j = 0; j < this.langs.length; j++){
    		//continuing if language is not active
    		if(!this.langs[j][2]) continue;
	    	//initializing lang result
	    	var lang_result = new Array();
	    	//getting required array for current lang
	    	for(var i = 0; i < this.ctrls.length; i++){  
	    		if(this.ctrls[i][2] && !this._get_lang_ctrl_value(this.ctrls[i][0], this.langs[j][0]))
	    			lang_result[lang_result.length] = this.ctrls[i][0];
	    	}	
			//setting global required array
			if(lang_result.length != 0)
	    		result[result.length] = lang_result;
    	}
    	//returning result
    	if(result.length == 0) 
    		return false;
    	else
    		return result;
    }
    
    
    //check required fields for lang code
    CLangmgr.prototype.check_required_ctrl_lang = function(ctrl_id, code){
    	lang = this.get_lang(code);
    	if(!lang) return false;
    	if(!lang[2]) return false;
    	//updating lang controls
    	this.update_lang_ctrls(this.active_lang_code);
    	//initializing result
    	var result = false;
    	//getting required array
    	for(var i = 0; i < this.ctrls.length; i++){  
            if(this.ctrls[i][0] == ctrl_id){
    		    if(this.ctrls[i][2] && !this._get_lang_ctrl_value(this.ctrls[i][0], code))
    			    result = true;
                break;
            }
    	}	
    	//returning result
    	return result;
    }
    
    //check required fields for all languages
    CLangmgr.prototype.check_required_ctrl = function(ctrl_id){
    	//updating lang controls
    	this.update_lang_ctrls(this.active_lang_code);
    	//initializing result
    	var result = new Array();
    	//getting required array
    	for(var j = 0; j < this.langs.length; j++){
    		//continuing if language is not active
    		if(!this.langs[j][2]) continue;
	    	//initializing lang result
	    	var result = new Array();
	    	//getting required array for current lang
	    	for(var i = 0; i < this.ctrls.length; i++){  
                if(this.ctrls[i][0] == ctrl_id){
	    		    if(this.ctrls[i][2] && !this._get_lang_ctrl_value(this.ctrls[i][0], this.langs[j][0]))
	    			    result[result.length] = this.langs[j][0];
                    break;
                }
	    	}	
    	}
    	//returning result
    	if(result.length == 0) 
    		return false;
    	else
    		return result;
    }
    
