// =================================
// 			  méthodes
// ---------------------------------

// insere 1 élément user-input dans 1 matrice
Matrix.prototype.insertElement = function(field){
	// recupération des indices	 
	var i = field.name.substr(7,1)-1;
	var j = field.name.substr(9,1)-1;
	// modification de l'objet matrice
	this.values[i][j] = field.value;
}


// affiche les valeurs de la matrice dans la table/form (output)
Matrix.prototype.showValues = function(){
	var frm = document.getElementById(this.formID);
	for (var i=0;i<this.m;i++){
		for (var j=0;j<this.n;j++){
			eval("frm.element"+Number(i+1)+"_"+Number(j+1)+".value = "+this.values[i][j]);
	 	}
	}
	// ajuste les inputs en fonction des valeurs
	this.ajustInputs(); 
}

// cree le code html pour afficher la matrice ( m lignes et n colonnes)
Matrix.prototype.createHtml = function(classType){
// classType : 'M1', 'M2', 'P':
// couleurs par défaut définies en css, et "readonly" activé par défaut selon le cas
// possibilité de préciser une couleur différente ex: "P red"
// possibilité d'ajouter "readonly" pour des cas particuliers  ex: "M1 readonly"
// de plus, on rajoute le type de matrice (diagonale,regular...) qui active des couleurs par défaut
	
	// génère les styles pour la matrice
	classType = classType+' '+this.type;
	// génère les styles pour les tr en cas de "higlight" par ligne
	var trStyle = new Array(this.m);
	if ( (this.genereHighlight || this.heriteHighlight) && this.highlightLine){
		var str= this.highlightLine.toString();// pour javascript < 1.6 ( indexOf sur 1 array impossible)
		for (var k=0; k<this.m; k++){
			if ( str.indexOf(k+1) != -1){
				trStyle[k]=' highlight';
			}else{
				trStyle[k]="";
			}
		}
	}else{
		for (var k=0; k<this.m; k++){
			trStyle[k]="";
		}
	}
	// génère les styles pour les td en cas de "higlight" par colonne
	var tdStyle = new Array(this.n);
	if ( (this.genereHighlight || this.heriteHighlight) && this.highlightCol){
		var str= this.highlightCol.toString();// pour javascript < 1.6 ( indexOf sur 1 array impossible)
		for (var k=0; k<this.n; k++){
			if ( str.indexOf(k+1) != -1){
				tdStyle[k]=' highlight';
			}else{
				tdStyle[k]="";
			}
		}
	}else{
		for (var k=0; k<this.n; k++){
			tdStyle[k]="";
		}
	}
	
	// code html
	document.write('<form id="'+this.formID+'" action="javascript:return;">'+"\n");
	//alert('create Html '+this.values+'   '+classType);
	document.write('<table class="'+classType+'" cellpadding="O" cellspacing="0" border="1">'+"\n");
	// remplissage du tableau ligne par ligne
	for (var i=1;i<this.m+1;i++){
		document.write('<tr class="tr'+i+trStyle[i-1]+'">'+"\n");
		// remplissage colonne par colonne dans la ligne donnée
		for (var j=1;j<this.n+1;j++){
			if (classType.indexOf("readonly")== -1){
			// pas de "readonly" précisé: comportement normal
				if (this.type =='diagonale'){
				// matrice diagonale : seuls les éléments de la diagonale sont accessibles par l'utilisateur
					if ((classType.indexOf('M1') != -1 || classType.indexOf('M2'))!= -1 && i==j){
						document.write('<td class="td'+j+tdStyle[j-1]+'"><input name="element'+i+'_'+j+'" type="text" size="1" values="" maxlength="3" onchange="makeChanges(this)"/>'+"\n");
					}else if ( classType.indexOf('P') != -1 || i != j ){
						document.write('<td class="td'+j+' readonly'+tdStyle[j-1]+'"><input name="element'+i+'_'+j+'" type="text" class="readonly" size="1" readonly="readonly" values="" maxlength="5"/>'+"\n");
					}
				}else if (this.type =='regular' || this.type=='permutation'){
				// matrice classique : tous les éléments sont accessibles , sauf pour la matrice produit.
					if (classType.indexOf('M1') != -1 || classType.indexOf('M2') != -1){
						document.write('<td class="td'+j+tdStyle[j-1]+'"><input name="element'+i+'_'+j+'" type="text" size="1" values="" maxlength="3" onchange="makeChanges(this)"/>'+"\n");
					}else if ( classType.indexOf('P') != -1){
						document.write('<td class="td'+j+' readonly'+tdStyle[j-1]+'"><input name="element'+i+'_'+j+'" type="text" class="readonly" size="1" readonly="readonly" values="" maxlength="5"/>'+"\n");
					}
				}
			}else if (classType.indexOf("readonly") != -1){
			// "readonly précisé: aucun élément accessible
				document.write('<td class="td'+j+' readonly'+tdStyle[j-1]+'"><input name="element'+i+'_'+j+'" type="text" class="readonly" size="1" readonly="readonly" values="" maxlength="5"/>'+"\n");
			}
			document.write('</td>'+"\n");
		}
		document.write('<tr>'+"\n");
	}
	document.write('</table>'+"\n");
	document.write('</form>'+"\n");
	// insere les valeurs
	this.showValues();
}

// ajuste la taille du contenu des champs input d'1 matrice
Matrix.prototype.ajustInputs = function(){
	var frm = document.getElementById(this.formID);
	var field;
	for (var i=0; i<this.m; i++){
		for (var j=0; j<this.n; j++){
			field = eval("frm.element"+Number(i+1)+"_"+Number(j+1));
			ajustField(field);
		}
	}
}

// mise à jour d'une matrice
Matrix.prototype.miseAJour = function(){
	/****  mise a jour des valeurs dépendantes ( matrices inverses, matrices copies...) *******/
	// si la matrice est une inverse, elle suit les changements de la matrice dont elle est l'inverse
	// NB: ici, le cas simplifié d'une diagonale inverse 
	if (this.inverse){
		var dim = this.original.m;
		for (var i=0;i<dim;i++){
			this.values[i][i]= 1/ this.original.values[i][i];
		}
	}
	// si la matrice est une copie, elle suit les changements de la matrice d'origine.
	else if (this.copie){
		 this.values = this.original.values;
	}
	
	/****  mise a jour des higlights *******/
	
	// les matrices qui génèrent leur propre highlight
	if (this.genereHighlight){
		// cas 1: matrice de permutation
		if(this.type=='permutation' && this.highlightLine){
			var lignes = new Array();
			var k=0;
			// find the permutation lines
			for (var i=0; i<this.m; i++){
				var nbreDe1parLigne =0;	// en dehors de la diagonale
				var resteNul=true;
				for (var j=0; j<this.n; j++){	
					if 	(this.values[i][j] == 1 && i!=j){
						 nbreDe1parLigne++;
					}else if (this.values[i][j] != 0){
						resteNul=false;
					} 
				}
				if (nbreDe1parLigne == 1 && resteNul ){
					lignes[k]= i+1;
					k++;
				}
			}
			// deletes the old higlights
			var el= getElementsByClass('highlight',document.getElementById(this.formID));
			for (var i=0;i<el.length;i++){
				el[i].className = el[i].className.replace(' highlight','');
				//alert(this.formID+' delete higlight généré'+el[i].className);	
			}
			// set the new highlights
			this.highlightLine=lignes;
			this.product.p.highlightLine=lignes;
			//alert('affecte le highlight au produit: '+this.product.p.highlightLine);
			for( i=0;i<lignes.length;i++){
				var elem= getElementsByClass('tr'+lignes[i],document.getElementById(this.formID));
				//alert(this.formID+' génère highlight '+elem[0].className);
				elem[0].className +=' highlight';
			}
		}
		if(this.type=='permutation' && this.highlightCol){
			var cols = new Array();
			var k=0;
			// find the permutation columns
			for (var j=0; j<this.n; j++){
				var nbreDe1parCol =0;	// en dehors de la diagonale
				var resteNul=true;
				for (var i=0; i<this.m; i++){	
					if 	(this.values[i][j] == 1 && i!=j ){
						 nbreDe1parCol++;
					}else if (this.values[i][j] !=0){
						resteNul=false;
					}
				}
				if (nbreDe1parCol == 1 && resteNul){
					cols[k]= j+1;
					k++;
				}
			}
			// deletes the old higlights
			var el= getElementsByClass('highlight',document.getElementById(this.formID));
			for (var i=0;i<el.length;i++){
				el[i].className = el[i].className.replace(' highlight','');
				//alert(this.formID+' delete higlight généré'+el[i].className);	
			}
			// set the new highlights
			this.highlightCol=cols;
			this.product.p.highlightCol=cols;
			//alert('affecte le highlight au produit: '+this.product.p.highlightLine);
			for( i=0;i<cols.length;i++){
				var elem= getElementsByClass('td'+cols[i],document.getElementById(this.formID));
				//alert(this.formID+' génère highlight '+elem[0].className);
				for ( j=0; j<elem.length;j++){
					elem[j].className +=' highlight';
				}
			}
		}
	}
	
	// les matrices qui héritent d'un highlight venant d'autres matrices
	if (this.heriteHighlight){
		// 1) récupératin du higlight
		// si la matrice est une copie, elle prend le hightline de l'original
		if (this.copie && this.highlightLine){
			 this.highlightLine = this.original.highlightLine;
		}else if (this.copie && this.highlightCol){
			 this.highlightCol = this.original.highlightCol;
		}
		// NB: si ce n'est pas une copie, elle a déjà hérité du highlight lors de la mise à jour de la matrice qui génère le higlight
		
		// 2) affichage du highlight hérité
		
		// efface les vieux higlights en html
		var el= getElementsByClass('highlight',document.getElementById(this.formID));
		for (var i=0;i<el.length;i++){
			el[i].className = el[i].className.replace(' highlight','');
			//alert('delete highlight hérité');
			//alert(this.formID+' delete '+el[i].className);	
		}
		// set the new highlights
		//alert(this.values);
		//alert(this.highlightLine);
		var l= new Array();
		if (this.highlightLine){
			l= this.highlightLine;
			//alert('herite highlightline : '+this.highlightLine);
			for( i=0;i<l.length;i++){
				var elem= getElementsByClass('tr'+l[i],document.getElementById(this.formID));
				//alert(this.formID+' hérite highlight '+elem[0].className);
				elem[0].className +=' highlight';
			}
		}else if(this.highlightCol){
			l=this.highlightCol;
			for( i=0;i<l.length;i++){
				var elem= getElementsByClass('td'+l[i],document.getElementById(this.formID));
				//alert(this.formID+' hérite highlight '+elem[0].className);
				for ( j=0; j<elem.length;j++){
					elem[j].className +=' highlight';
				}
			}
		}
	}
}

