/********* Champ.js *********
** Permet la gestion des champs prédéfinis, via KnockoutJS
** Par Jean Thévenet (!nRed)
*****************************/
function triggererror(string,error)
	{
	if(error==true) { $( ".error label" ).css('color','darkred'); }
	else { $( ".error label" ).css('color','darkgreen'); }

	vm.error(string);

	$( ".error" ).fadeIn(400).delay(1500).fadeOut(400);
	}
function loadOptions(type) // Définit les différentes options disponibles
	{
	if(type=='paragraphe'||type=='texte')
		{
		options= {size:["small","medium","large"],minlength:0,maxlength:0,min_max_length_units:["characters","words"]};
		}
	else if(type=='case à cocher'||type=='menu déroulant'||type=='choix multiple')
		{
		options = {options:[{label: "",checked: false}, {label: "",checked: false}],include_blank_option:[true,false]};
		}
	return options;
	}

function convertToObservable(list) // Convertis un tableau/objet tableau/objet constitué d'observables
{ 
	var newList = []; 
	$.each(list, function (i, obj) {
		if(obj instanceof Object)
			{
			var newObj = {}; 
			Object.keys(obj).forEach(function (key) { 
			if(obj[key] instanceof Array || obj[key] instanceof Object)
				{
				 newObj[key] = convertToObservable(obj[key]); 
				}
			else
				{
				newObj[key] = ko.observable(obj[key]); 
				}
			}); 
			}
		else
		{
		newObj=ko.observable(list[i]);
		}
		newList.push(newObj); 
	}); 
	return newList; 
}
var ViewModel = function(urlJson,urlPost,urlExport,champs,types) { // Principal container
vm=this;
this.table = convertToObservable(champs); // Tableau principal de valeurs


this.error = ko.observable(''); // Erreur

this.id = ko.observable(0); // Identifiant du formulaire
this.formedit = ko.observable('Créer nouveau'); // Texte

// Champ sélectionné :
this.edit_field_nom = ko.observable(''); // Nom
this.edit_field_typechamp = ko.observableArray(types); // Array des différents types de champs
this.edit_field_typechamp_selected = ko.observableArray([]); // Type de champ sélectionné
this.edit_field_options = ko.observableArray([]); // Options en observableArray

// valeurs par défaut :
this.size=ko.observableArray(["petit","moyen","grand"]);
this.size_selected=ko.observableArray(); // Taille sélectionné
this.num_min=ko.observable(''); // Minimum de mots/caractères pour les champs texte
this.num_max=ko.observable(''); // Maximum de mots/caractères pour les champs texte
this.units=ko.observableArray(["caractères","mots"]);
this.units_selected=ko.observableArray(); // Unité sélectionnée
this.newOpt_selected=ko.observable(false); // Option defaut ou non
this.newOpt_name=ko.observable(''); // Nom de l'option
this.numOptionSelected=ko.observable(-1); // num option sélectionnée
this.edit_field_options_selected=ko.observableArray(); // valeur option selectionnée
this.addModifyOpt=ko.observable(''); // 'Ajouter'/'Modifier' string
this.editable=new Array; // Options non observableArray mais constitué d'observables
this.OptSelected=ko.observable(); // En cas d'event, correspond à l'option venant d'être sélectionnée
this.include_blank_option=ko.observable(false); // Case Inclure un champ autre/vide
this.selectORcheck=ko.observable(); // <select> ou autre
this.exporthref=ko.observable();
this.alphasort=ko.observable(false);
this.newOpt=function() // Click sur Nouvelle option
	{
	vm.addModifyOpt('Ajouter');
	$( '.selectOptButtons' ).hide();
	$( '.newOpt' ).show();
	};

this.addOpt=function() // Click sur ajouter option
	{
	$( '.newOpt' ).hide();
	if(ko.toJS(vm.newOpt_selected)==true) n=' (Sélectionné)';
	else n='';
	var visuel=ko.toJS(vm.newOpt_name)+n;
	if(ko.toJS(vm.addModifyOpt)=='Ajouter')
		{
		count=ko.toJS(vm.editable).length;
		vm.editable[count]=ko.observable(visuel);
		}
	else
		{
		n=ko.toJS(vm.numOptionSelected);

		vm.editable[n](visuel);
		}
	vm.newOpt_selected(false);
	vm.newOpt_name('');
	vm.edit_field_options.removeAll()
	for (var i=0,j=vm.editable.length; i<j; i+=1)
		{
		vm.edit_field_options.push(vm.editable[i]);
		}
	$( '.selectOptButtons' ).show();
	};

/* Selon le type de champ sélectionné, on affiche les options correspondantes */
this.edit_field_typechamp_selected.subscribe(function(typeChampSelected) { // Event fired quand sélectionne une option
if(typeChampSelected=='paragraphe'||typeChampSelected=='texte')
	{
	$( '.selectopt' ).hide();
	$( '.textopt' ).show();
	}
else
	{
	if(typeChampSelected=='menu déroulant') { vm.selectORcheck('vide'); }
	else vm.selectORcheck('"autre"');
	$( '.textopt' ).hide();
	$( '.selectopt' ).show();
	}
});

/* On récupère l'index de l'option sélectionnée et l'enregistre dans un observable (pour modifier la valeur dans l'array) */
this.edit_field_options_selected.subscribe(function(OptSelected) 
	{
	$( '.newOpt' ).hide();
	$( '.selectOptButtons' ).show();
	vm.OptSelected(OptSelected); // Sinon impossible de récupérer OptSelected dans le SetTimeout

	setTimeout(function() 
		{  // SetTimeout car le script met un peu de temps à refaire l'Array (obtient des "undefined)
		OptSelected=ko.toJS(vm.OptSelected);
		OptSelected=OptSelected[0].trim();

		arr=ko.toJS(vm.editable);
		for(var i=0, j=arr.length; i<j; i++)
			{
			if(OptSelected==arr[i]) { num=i; break; } // Récupère l'index de la case sélectionnée
			}

		vm.numOptionSelected(num); // On enregistre
		}, 80);
	});

this.modifyOpt=function() // Bouton modifier une option
	{
	n=ko.toJS(vm.numOptionSelected);
	tmp=vm.edit_field_options()[n];
	tmp=ko.toJS(tmp);

	tmp=tmp.split(' ');
	index=tmp.length;
	index-=1;
	if(tmp[index]=='(Sélectionné)') { selected=true; tmp.splice(index,1); }
	else { selected=false; }

	tmp=tmp.join(' ');
	vm.newOpt_selected(selected);

	vm.newOpt_name(tmp);
	vm.addModifyOpt('Enregistrer les modifs');
	$( '.newOpt' ).show();
	$( '.selectOptButtons' ).hide();
	};
this.deleteOpt=function() // Bouton supprimer une option
	{
	n=ko.toJS(vm.numOptionSelected);
	tmp=vm.edit_field_options.splice(n,1);
	vm.editable.splice(n,1);
	};

this.save = function() // Bouton Enregistrer
	{
	var type=ko.toJS(vm.edit_field_typechamp_selected)[0];
	var savethis={original:type,nom:ko.toJS(vm.edit_field_nom)};
	var fail;
	/* On récupère les options sélectionnées : */
	if(type=='paragraphe'||type=='texte') // Cas "texte"
		{
		savethis['type']='text';
		var min=ko.toJS(vm.num_min),max=ko.toJS(vm.num_max),units=ko.toJS(vm.units_selected),size=ko.toJS(vm.size_selected);

		if(typeof min!== 'undefined'&&min!=='') savethis['min']=min;
		if(typeof max!== 'undefined'&&max!=='') savethis['max']=max;
		if(typeof units!== 'undefined'&&units.length!=0) savethis['units']=units;
		if(typeof size!== 'undefined'&&size.length!=0) savethis['size']=size;
		}
	else // Cas autres
		{
		savethis['type']='other';
		var options=ko.toJS(vm.editable);
		if(ko.toJS(vm.alphasort)==true)
			{
			options.sort();
			}
		if(options.length>0) savethis['options']=options;

		blank=ko.toJS(vm.include_blank_option);

		if(typeof blank!== 'undefined' && blank!==false)
			{
			savethis['include_blank_option']=true;
			}
		}

	idid=ko.toJS(vm.id); // id du champ prédéfini

	if (savethis.nom=='')
		{
		triggererror('Vous devez définir un nom !',true);
		}
	else if(typeof savethis.original == 'undefined')
		{
		triggererror('Vous devez définir le type de champ !',true);
		}
	else if(Object.keys(savethis).length<=3) // Vérifie qu'au moins une option à été modifiée (sinon ca ne sert à rien de créer un champ prédéfini)
		{
		triggererror('Vous n\'avez défini aucune option !',true);
		}
	else
		{
		savethis=JSON.stringify(savethis); // Convertit les options en json
		$.post(urlJson+idid, { 'data[]':savethis }, function(returnedData) { // Envoie le json au backend

		if(returnedData=='ok') // Backend à bien effectué la mise à jour
			{
			triggererror('Modifications enregistrées.',false);
			if(idid==-1) location.reload();
			var chose=0;
			if(idid!=-1)
				{
				$.each(ko.toJS(vm.table),function(key,value)
					{
					if(value['id']==idid) { chose=key; }
					});

				vm.table[chose]['name'](ko.toJS(vm.edit_field_nom)); // Met à jour le tableau principal de gauche avec les nouvelles options
				vm.table[chose]['type'](ko.toJS(vm.edit_field_typechamp_selected));
				}
			}
		else
			{ // Oh GOD something went terribly wrong! 
			triggererror('Impossible d\'enregistrer les modifications',true);
			}
		});

		}
	};
this.cancel=function() // Bouton annuler
	{
	$( ".item_edit_container" ).fadeOut(400);
	}
this.deleteForm=function() // Bouton supprimer un formulaire (copié collé de custom.js)
	{
	if(confirm('Êtes-vous sûr(e) de vouloir supprimer le champ '+ko.toJS(vm.edit_field_nom)+' ?')==true)
		{
		idid=$( "#id_form" ).val();
		$.post(urlJson+idid, { delete:true }, function(returnedData) {
		if(returnedData=='ok')
			{
			vm.error('Modifications enregistrées');
			$( ".error label" ).css("color","darkgreen");
			location.reload();
			}
		else
			{
			vm.error('Impossible de supprimer ce formulaire');
			$( ".error label" ).css("color","darkred");
			}
		$( ".error" ).fadeIn(200).delay(1500).fadeOut(400);
		});
		}
	}
this.newchamp=function() // Bouton Nouveau champ
	{
	$( ".export" ).hide();
	$( '.newOpt' ).hide();
	$( '.selectOptButtons' ).show();
	$( ".loading" ).hide();
	$( ".deleteF" ).hide();
	$( ".item_edit_container" ).show();
	vm.formedit('Nouveau champ');
	$( ".greyButton" ).hide();
	// On remet toutes les valeurs par défaut:
	vm.id(-1);
	formid=-1;
	vm.units_selected.removeAll();
	vm.edit_field_options.removeAll();
	vm.edit_field_options_selected.removeAll();
	vm.include_blank_option(false);
	vm.editable=new Array;
	vm.size_selected.removeAll();
	vm.num_min();
	vm.num_max();

	vm.edit_field_nom('');
	vm.edit_field_typechamp_selected([]);

	$( ".options" ).hide();
	}
this.getFormInfo = function(data) { // Récupère les infos nécessaires sur un champ prédéfini
	$( ".deleteF" ).show();
	$( '.newOpt' ).hide();
	$( '.selectOptButtons' ).show();
	formid=ko.toJS(this.id); //id du champ sélectionné
	vm.exporthref(urlExport+formid+'/champs');
	vm.id(formid); // on enregistre l'id pour plus tard
	$.getJSON(urlJson+formid, function(data) { // Demande les infos au backend
		$( ".greyButton" ).show();
		$( ".loading" ).hide();
		$( ".export" ).show();
		$( ".item_edit_container" ).show();
		vm.formedit('Éditer un champ');
		data=data[0];
		vm.edit_field_nom(data.nom);
		vm.edit_field_typechamp_selected([data.type]);
		options=JSON.parse(data.options);
		if(data.type=='menu déroulant'||data.type=='case à cocher'||data.type=='choix multiple')
			{
			vm.edit_field_options.removeAll() // mise à jour du tableau des options
			for(var i=0, j=options.length; i<j; i++)
				{
				vm.edit_field_options.push(options[i]);
				}
			vm.editable=convertToObservable(options); // mise à jour du deuxième tableau d'options
			vm.include_blank_option(data.otherOptions.include_blank_option); // bouton à cocher inclure champ autre/vide
			}
		else // Champ simple
			{
			vm.size_selected.removeAll();
			vm.size_selected.push(options.size); //maj opt
			vm.num_min(options.min);
			vm.num_max(options.max);
			vm.units_selected.removeAll();
			vm.units_selected.push(options.units);
			}
	});
};
};