/*---------------------------------------------------------------------------
		File name ............ canvas/js/utils.form.js
		Author ............... Antoine Lemoine
		Creation date ........ 22.10.2008
		Modification date .... 22.10.2008
---------------------------------------------------------------------------*/


if (!include)
{
	alert("`utils.form.js` requires `utils.core.js`");
}

include('canvas/js/utils.array.js');
include('canvas/js/utils.string.js');
includeCSS('canvas/css/form.css');

var FIELDS_COUNTER = 0;

var DatePicker = function (input, form_enhancer)
{
	this.form_enhancer = form_enhancer;
	this.jinput = $(input);
	this.name = this.jinput.attr('name');
	this.jinput.attr('id',name);
	this.jinput.addClass('form-ui-dp');
	var offset = this.jinput.offset();
	
	this.jcalendar = $("<div class=\"form-ui-dp-container\" style=\"position:absolute;z-index:2;display:none;\"></div>");
	this.jinput.before(this.jcalendar);
		
	var _self = this;
	this.jinput.focus(
		function (e)
		{
			_self.showDatePicker();
		}
	);
	this.jinput.blur(
		function (event)
		{
			var elem = jQuery.browser.mozilla ? event.originalEvent.explicitOriginalTarget : document.activeElement;

			while (true)
			{
				if (elem==_self.jcalendar[0])
				{
					return false;
				}
				else if (elem==document)
				{
					_self.hideDatePicker();
					return true;
				}
				else
				{
					elem = $(elem).parent()[0];
					if (elem==null)
					{
						return false;
					}
				}
			}
		}
	);
	this.jinput.attr('autocomplete','off');

	/* --- Méthodes --- */
	
	this._setDate = function (caller)
	{
		var value = $(caller).attr('id').substr(11);
		this.setDate(value);
	}

	// Sélection de dates
	this.setDate = function (date)
	{
		this.jinput.val(date);
		this.jinput.change();
		this.hideDatePicker();
	}
	
	this.hideDatePicker = function ()
	{
		//this.jcalendar.empty();
		this.jcalendar.hide();
	}

	this.showDatePicker = function ()
	{
		if (this.jcalendar.css('display')=='none')
		{
			this.jcalendar.css('top',this.jinput.offset().top+this.jinput.outerHeight());
			this.jcalendar.css('left',this.jinput.offset().left);
			var year = month = day = null;
			var value = this.jinput.val();
			if (value==null || value=='' || value=='0000-00-00')
			{
				var date = new Date();
				year = date.getFullYear();
				month = date.getMonth()+1;
				day = date.getDate();
			}
			else
			{
				var date_array = value.split('-');
				year = parseInt(date_array[0]);
				month = parseInt(date_array[1]);
				day = parseInt(date_array[2]);
			}
			this.refreshCalendar(year,month,year,month,day);
			this.jcalendar.show();
		}
	}

	this._refreshCalendar = function (caller)
	{
		var data = $(caller).attr('id').substr(11).split('-');
		this.refreshCalendar(parseInt(data[0]),parseInt(data[1]),parseInt(data[2]),parseInt(data[3]),parseInt(data[4]));
		this.jinput.focus();
	}

	this.refreshCalendar = function (year, month, selected_year, selected_month, selected_day)
	{
		if (month<1)
		{
			var n = Math.floor(-month/12)+1;
			month += n*12;
			year -= n;
		}
		else if (month>12)
		{
			var n = Math.floor(month/12);
			month -= n*12;
			year += n;
		}
		
		var date = new Date(year,month-1,1,0,0,0);
		var current_date = new Date();
		var current_year = current_date.getFullYear();
		var current_month = current_date.getMonth()+1;
		var current_day = current_date.getDate();
		
		var month_names = ['Jan.','Fév.','Mars','Avril','Mai','Juin','Juil.','Août','Sep.','Oct.','Nov.','Déc.'];
	
		var selected_date = selected_year+'-'+selected_month+'-'+selected_day;
		var calendar = "<table class=\"form-ui-dp-calendar"
			+ (year<current_year || year==current_year && month<current_month ? ' past' : '')+"\">"
			+ "<thead><tr class=\"form-ui-dp-title\">"
//				+"<span class=\"form-ui-dp-refresh\">&gt;</span>"
//				+"<span class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+(year+1)+"-"+month+"-"+selected_date+"\" title=\"Année suivante\"></span></div>"
			+ "<th class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+(year-1)+"-"+month+"-"+selected_date+"\" title=\"Année précédente\">&lt;&lt;</th>"
			+ "<th class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+year+"-"+(month-1)+"-"+selected_date+"\" title=\"Mois précédent\">&lt;</th>"
//			+ "<div style=\"float:left\">"
//				+"<span class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+(year-1)+"-"+month+"-"+selected_date+"\" title=\"Année précédente\">&lt;&lt;</span>"
//				+"<span class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+year+"-"+(month-1)+"-"+selected_date+"\" title=\"Mois précédent\">&lt;</span></div>"
			+ "<th class=\"form-ui-dp-title\" colspan=\"3\">"+month_names[month-1]+"&nbsp;"+year+"</th>"
			+ "<th class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+year+"-"+(month+1)+"-"+selected_date+"\" title=\"Mois suivant\">&gt;</th>"
			+ "<th class=\"form-ui-dp-refresh\" id=\"dp_refresh_"+(year+1)+"-"+month+"-"+selected_date+"\" title=\"Année suivante\">&gt;&gt;</th>"
			+ "</tr></thead><tbody>"
			+ "<tr class=\"form-ui-dp-day_names\"><th>L</th><th>M</th><th>M</th><th>J</th><th>V</th><th>S</th><th>D</th></tr>";
	
		var x=0;
		var day = 1;
	
		var days_number = 31;
		if (month==4 || month==6 || month==9 || month==11) { --days_number; }
		if (month==2) {
			days_number = days_number - 3;
			if (year%4==0) { days_number++; }
			if (year%100==0) { days_number--; }
			if (year%400==0) { days_number++; }
		}
		
		var first_day_number = date.getDay();
		if (first_day_number==0) { first_day_number = 7; }
		
		while (day<=days_number)
		{
			if (x%7==0)
			{
				calendar += "<tr>";
				if (day==1)
				{
					// On crée toutes les cases vides nécessaires
					// pour placer le premier du mois au bon endroit
					for (var i=1; i<first_day_number; i++)
					{
						calendar += "<td class=\"day inexistant_day\">&nbsp;</td>";
						x++;
					}
				}
			}
	
			var class_name = 'day'
				+(year==selected_year && month==selected_month && day==selected_day ? ' selected_day'
					: (year==current_year && month==current_month && day==current_day ? ' today' : ''));
			calendar += "<td class=\""+class_name+"\"><span class=\"form-ui-dp-setdate\" id=\"dp_setdate_"+sprintf('%04d-%02d-%02d',year,month,day)+"\">"+day+"</span></td>";
			x++;
			if (x%7==0) { calendar += "</tr>"; }
			day++;
		}
		
		if (day>days_number && x%7!=0)
		{
			for (i=(first_day_number-1+days_number)%7; i<7; i++)
			{
				calendar += "<td class=\"day inexistant_day"+((x%7)==6 ? ' dimanche' : '')+"\">&nbsp;</td>";
				x++;
			}
			calendar += "</tr>";
		}
		
		calendar += "</tbody></table>";
		
		var jcalendar_table = $(calendar);
		this.jcalendar.html(jcalendar_table);

		var _self = this;
		jcalendar_table.find('.form-ui-dp-refresh').click(
			function ()
			{
				_self._refreshCalendar(this);
			}
		);
		jcalendar_table.find('.form-ui-dp-setdate').click(
			function ()
			{
				_self._setDate(this);
			}
		);
	}
}


var RichTextField = function (elem, form_enhancer)
{
	this.unique_id = FIELDS_COUNTER++;
	this.form_enhancer = form_enhancer;
	this.jelem = $(elem);
	this.jtoolbar = null;
	this.iframe = null;

	this.init = function ()
	{
		this.jelem.hide();
		
		this.field_id = this.jelem.attr('id');
		if (this.field_id==null)
		{
			this.field_id = 'richtext-editor-'+this.unique_id;
		}
		else
		{
			this.jelem.removeAttr('id');
		}
	
		this.name = this.jelem.attr('name');
		this.jelem.wrap("<div id=\""+this.field_id+"\" class=\"richtext-editor\"></div>");
		this.jelem.before("<div id=\"richtext-toolbar-"+this.unique_id+"\" class=\"richtext-toolbar\" style=\"margin-top:5px;\"> "
			+ "<img class=\"btn-undo\" title=\"Annuler\" /><img class=\"btn-redo\" title=\"Restaurer\" /> "
			+ "<img class=\"btn-bold\" title=\"Mettre en gras\" /><img class=\"btn-italic\" title=\"Mettre en italique\" />"
			+ "<img class=\"btn-underline\" title=\"Souligner\" /> "
			+ "<img class=\"btn-insertunorderedlist\" title=\"Insérer une liste\" /><img class=\"btn-outdent\" title=\"Indenter moins\" />"
			+ "<img class=\"btn-indent\" title=\"Indenter plus\" /> "
			+ "<img class=\"btn-removeformat\" title=\"Supprimer le formatage\" /></div>"
			+ "<div class=\"richtext-frame-container\">"
			+ "<iframe class=\"richtext-frame "+this.jelem.attr('class')+" textfield\" frameborder=\"0\" style=\"margin:0;\"></iframe></div>");
	
		this.iframe = $('#'+this.field_id+' .richtext-frame').get(0);
		this.jtoolbar = $('#'+this.field_id+' .richtext-toolbar');
		this.jiframe_container = $('#'+this.field_id+' .richtext-frame-container');
		
		var jiframe = $(this.iframe);
		/* Correction d'un bug d'affichage sous Firefox */
		this.jiframe_container.css('padding-right',(parseInt(jiframe.css('border-left-width'))+parseInt(jiframe.css('border-right-width')))+'px')

		var owner = this;
		this.jelem.parents('form').submit(
			function ()
			{
				owner.save();
			}
		);

		this.enabledDesignMode();
	
		var jbuttons = this.jelem.siblings('.richtext-toolbar').children('img');
		jbuttons.css('vertical-align','bottom');
		for (var i=0; i<jbuttons.size(); i++)
		{
			var jbutton = jbuttons.eq(i);
			var name = jbutton.attr('class').substr(4);
			jbutton.attr('src',this.form_enhancer.images_path+'/richtext/'+name+'.png');
			jbutton.click(
				function ()
				{
					var content_document = owner.getContentDocument();
					var jcontent_document = $(content_document);
					jcontent_document.focus();
					var cmd = $(this).attr('class').substr(4);
					content_document.execCommand('styleWithCSS', false, false);
					content_document.execCommand(cmd,false,null);
					form_enhancer.checkModification(content_document,false);
					jcontent_document.focus();
					$(owner.iframe.contentWindow).focus();
				}
			);
		}
	}

	this.getContentDocument = function ()
	{
		if (jQuery.browser=='MSIE') { return this.iframe.document; }
		else { return this.iframe.contentDocument; }
	}

	this.save = function ()
	{
		this.jelem.val($(this.getContentDocument()).find('body').html());
	}
	
	this.enabledDesignMode = function ()
	{
		var document_content = "<html><head><style>body{margin:0;padding:1px;font-family:Microsoft Sans Serif;font-size:8pt;}</style></head>"
			+ "<body id=\"richtext-document"+this.unique_id+"\">"+this.jelem.val()+"</body></html>";

		var content_document = this.getContentDocument();
		this.iframe.content_document = content_document;

		try
		{
			content_document.open();
			content_document.write(document_content);
			content_document.close();
		}
		catch (error) { alert(error); }
		
		var jcontent_document = $(content_document);
		var owner = this;

		jcontent_document.focus(
			function ()
			{
				$('#'+owner.field_id).addClass('textfield-focused');
			}
		);
		jcontent_document.blur(
			function ()
			{
				$('#'+owner.field_id).removeClass('textfield-focused');
			}
		);

		if (document.contentEditable)
		{
			content_document.designMode = 'On';
			return true;
		}
		else if (document.designMode!=null)
		{
			try
			{
				content_document.designMode = 'on';
				return true;
			}
			catch (error) { alert(error); }
		}

		return false;
	}

	this.init();
}

var EmailField = function (elem, form_enhancer)
{
	this.unique_id = FIELDS_COUNTER++;
	this.form_enhancer = form_enhancer;

	this.jelem = $(elem);
	this.name = this.jelem.attr('name');
	this.jelem.attr('id',name);
	this.jelem.wrap("<span class=\"field-container\"></span>");
	this.jelem.after("<a id=\"efml_"+this.unique_id+"\" href=\"mailto:"+this.jelem.val()+"\" target=\"_blank\">"
		+ "<img src=\""+this.form_enhancer.images_path+"/email.png\" style=\"border:0;vertical-align:bottom;margin-left:5px;\" /></a>");

	var owner = this;
	this.jelem.keyup(
		function ()
		{
			$('#efml_'+owner.unique_id).attr('href','mailto:'+owner.jelem.val());
		}
	);
}

var LinkField = function (elem, form_enhancer)
{
	this.unique_id = FIELDS_COUNTER++;
	this.form_enhancer = form_enhancer;

	this.jelem = $(elem);
	this.name = this.jelem.attr('name');
	this.jelem.attr('id',name);
	this.jelem.wrap("<span class=\"field-container\"></span>");
	this.jelem.after("<a id=\"wfl_"+this.unique_id+"\" href=\""+buildPath(this.jelem.attr('path'),this.jelem.val())+"\" target=\"_blank\">"
		+ "<img src=\""+this.form_enhancer.images_path+"/link.png\" style=\"border:0;vertical-align:bottom;margin-left:5px;\" /></a>");

	var owner = this;
	if (this.jelem.change)
	{
		this.jelem.change(
			function ()
			{
				owner.updateLink();
			}
		);
	}
	this.jelem.keyup(
		function ()
		{
			owner.updateLink();
		}
	);
	
	this.updateLink = function ()
	{
		var path = owner.jelem.attr('path');
		$('#wfl_'+owner.unique_id).attr('href',(path!=null ? path+'/' : '')+owner.jelem.val());
	}
}

var WebsiteField = function (elem, form_enhancer)
{
	this.unique_id = FIELDS_COUNTER++;
	this.form_enhancer = form_enhancer;

	this.jelem = $(elem);
	this.name = this.jelem.attr('name');
	this.jelem.attr('id',name);
	this.jelem.wrap("<span class=\"field-container\"></span>");
	this.jelem.after("<a id=\"wfl_"+this.unique_id+"\" href=\""+this.jelem.val()+"\" target=\"_blank\">"
		+ "<img src=\""+this.form_enhancer.images_path+"/website.png\" style=\"border:0;vertical-align:bottom;margin-left:5px;\" /></a>");

	var owner = this;
	if (this.jelem.change)
	{
		this.jelem.change(
			function ()
			{
				owner.updateLink();
			}
		);
	}
	this.jelem.keyup(
		function ()
		{
			owner.updateLink();
		}
	);
	
	this.updateLink = function ()
	{
		$('#wfl_'+owner.unique_id).attr('href',owner.jelem.val());
	}
}

var CheckboxField = function (elem, form_enhancer)
{
	this.form_enhancer = form_enhancer;
	this.jcheckbox = $(elem);
	this.jimage = null;
	this.focused = false;

	this.init = function ()
	{
		this.jcheckbox.css({'opacity':0,'z-index':10,'position':'absolute'});
		this.jimage = $('<img style="vertical-align:top;" src="'+this.form_enhancer.images_path+'/checkbox/checkbox-unchecked.png" />');
		this.jcheckbox.after(this.jimage);
		this.jcheckbox.css({'width':this.jimage.width()+'px','height':this.jimage.height()+'px'});

		var _self = this;
		this.jcheckbox.click(
			function ()
			{
				_self.update();
			}
		);
		this.jcheckbox.focus(
			function ()
			{
				_self.focused = true;
				_self.update();
			}
		);
		this.jcheckbox.blur(
			function ()
			{
				_self.focused = false;
				_self.update();
			}
		);
		
		this.update();
	}
	
	this.update = function ()
	{
		var src = this.form_enhancer.images_path+'/checkbox/checkbox-'+(this.jcheckbox.attr('readonly') ? 'readonly-' : (this.focused ? 'focused-' : ''))
			+(!this.jcheckbox.attr('checked') ? 'un' : '')+'checked.png';
		this.jimage.attr('src',src);
	}
		
	this.init();
}

var RadioField = function (elem, form_enhancer)
{
	this.form_enhancer = form_enhancer;
	this.jradio = $(elem);
	this.name = this.jradio.attr('name');
	this.jimage = null;
	this.focused = false;

	this.init = function ()
	{
		this.jradio.css('opacity',0);
		this.jradio.css('z-index',10);
		this.jradio.css('position','absolute');
		this.jimage = $('<img class="radio-image-'+this.name
			+'" style="vertical-align:top;" src="'+this.form_enhancer.images_path+'/radio/radio-unchecked.png" />');
		this.jradio.after(this.jimage);
		this.jradio.css('width',this.jimage.width()+'px');
		this.jradio.css('height',this.jimage.height()+'px');
		
		var owner = this;
		this.jradio.click(
			function ()
			{
				owner.update();
			}
		);
		this.jradio.focus(
			function ()
			{
				owner.focused = true;
				owner.updateImage();
			}
		);
		this.jradio.blur(
			function ()
			{
				owner.focused = false;
				owner.updateImage();
			}
		);
		this.jimage.click(
			function ()
			{
				owner.updateImage();
			}
		);

		this.update();
	}
	
	this.update = function ()
	{
		this.updateImage();
		$('.radio-image-'+this.name).not(this.jimage).click();
	}
	
	this.updateImage = function ()
	{
		var src = this.form_enhancer.images_path+'/radio/radio-'+(this.jradio.attr('readonly') ? 'readonly-' : (this.focused ? 'focused-' : ''))
			+ (!this.jradio.attr('checked') ? 'un' : '')+'checked.png';
		this.jimage.attr('src',src);
	}
		
	this.init();
}

var FormEnhancer = function (allowed_fields)
{
	this.allowed_fields = new Array();
	for (i=0; i<allowed_fields.length; i++)
	{
		this.allowed_fields[allowed_fields[i]] = true;
	}
	this.images_path = 'canvas/images/form/';

	/* --- Méthodes --- */
	
	this.processFields = function (root_elements)
	{
		if (root_elements==null) { root_elements = $(document); }

		// Mise à jour de l'état des champs
		this.updateFields(root_elements);

		// Récupération des champs non traités
		var not_processed = root_elements.find('input,textarea,select').not('[@processed]');

		if (this.allowed_fields['datepicker'])
		{
			// Création des éléments date-picker
			var date_fields = not_processed.filter('.datepicker');
			for (var i=0; i<date_fields.size(); i++)
			{
				new DatePicker(date_fields.get(i),this);
			}
		}

		if (this.allowed_fields['email-field'])
		{
			// Création des éléments email-field
			var email_fields = not_processed.filter('.email-field');
			for (var i=0; i<email_fields.size(); i++)
			{
				new EmailField(email_fields.get(i),this);
			}
		}

		if (this.allowed_fields['website-field'])
		{
			// Création des éléments website-field
			var website_fields = not_processed.filter('.website-field');
			for (var i=0; i<website_fields.size(); i++)
			{
				new WebsiteField(website_fields.get(i),this);
			}
		}

		if (this.allowed_fields['link-field'])
		{
			// Création des éléments link-field
			var link_fields = not_processed.filter('.link-field');
			for (var i=0; i<link_fields.size(); i++)
			{
				new LinkField(link_fields.get(i),this);
			}
		}

		if (this.allowed_fields['textfield'])
		{
			// Traitement des champs standards
			not_processed.filter(':text, textarea, select').addClass('textfield');
		}

		if (this.allowed_fields['checkbox'])
		{
			// Traitement des checkbox
			//not_processed.filter(':checkbox').addClass('checkbox');
			var checkboxs = not_processed.filter(':checkbox');
			for (var i=0; i<checkboxs.size(); i++)
			{
				new CheckboxField(checkboxs.get(i),this);
			}
		}

		if (this.allowed_fields['radio'])
		{
			// Traitement des radio
			//not_processed.filter(':radio').addClass('radio');
			var radios = not_processed.filter(':radio');
			for (var i=0; i<radios.size(); i++)
			{
				new RadioField(radios.get(i),this);
			}
		}
		
		if (this.allowed_fields['richtext-field'])
		{
			// Traitement des champs richtext (à la fin car assez lourd)
			var richtext_fields = not_processed.filter('.richtext-field');
			for (var i=0; i<richtext_fields.size(); i++)
			{
				new RichTextField(richtext_fields.get(i),this);
			}
		}

		// Mise à jour de la valeur processed
		not_processed.attr('processed','true');
	}

	this.updateFields = function (root_elements)
	{
		if (root_elements==null) { root_elements = $(document); }

		root_elements.find('input[@readonly]:not(.readonly)').addClass('readonly');
		root_elements.find('input.readonly:not([@readonly])').removeClass('readonly');
	}
}


