


VIDEOTRON.widget.SO_optionList = function(elem, lang) {

	var _list_ = this;
	var YU = YAHOO.util;
	var _lg = document.documentElement.lang;
	var _ie = YAHOO.env.ua.ie;
	var langURL = 'FRENCH';
	var LIGNE_OPTIONS = 1;
	
	if(lang != null)
		langURL = lang;

	
	this.dict = (function () {
			return (_lg == 'fr') ? {free: 'Gratuit', included: 'Inclus', details: 'Détails', NotPerUnit: 'Non disponible à la carte', CaptionOption_1002 : 'Messages vocaux par courriel'} : {free: 'FREE', included: 'Included', details: 'Details', NotPerUnit: 'Non available a la carte', CaptionOption_1002 : 'Voice messages by email'};
			 
		})();
	
	if (typeof elem === "undefined" || !elem) {
		elem = 'options-wrapper';
	}
	// Récupère le wrapper
	var wrapper = (function () {
		var w = YU.Dom.get(elem);
		if((typeof w !== "undefined" && w)) return w;
		throw 'SO_optionList.wrapper :: ' + elem + ' not found!';
	})();
	
	// Création du table pour afficher les options. 
	var optTbl = (function() {
		var t = document.createElement('table');
		t.id = 'tbl-' + wrapper.id;
		t.className = 'clear';
		return t;
	})();
	
	// Collection de package
	var pkgs = (function() {
		var p = new Array();
		p.getPack = function(idx) {
			return p[idx];
		};
		return p;
	})();
	
	// Objet package
	var pkg = function() {
		var p = {};
		p.headCaption = ''
		p.packPrice = 0.0;
		p.index = 0;
		
		p.runningTotal = function() {
			var t = p.packPrice;
		    for (var opt in rows) {
		        if (rows.hasOwnProperty(opt)) {
					var o = rows[opt];
					if(!o.onUseFees && !o.packCells[p.index].isIncluded && !o.isFree && o.isChecked) 
						t += (!o.usePromo || (isFirst(o,p.index)&& p.index != LIGNE_OPTIONS)) ? o.monthlyFees : o.monthlyFeesAlt;
				}
			}
			return t;
		};
		return p;
	};
	
	// Fonctionnalité d'ajout de package
	var _addPackage = function (inf) {
		if(inf.headCaption && inf.packPrice) {
			var p = new pkg;
			p.headCaption = inf.headCaption;
			p.packPrice = inf.packPrice;
			p.index = pkgs.length;
			pkgs.push(p);
			return p;
		} else {
			throw 'SO_optionList :: Add package error. Missing information !';
		}
	};
	
	// Collection d'items (row dans le tableau)
	var rows = {};
	// Fonctionnalité d'ajout d'item
	var _addRow = function (data) {

		if (typeof data === 'object' && data.hasOwnProperty('id') && data.hasOwnProperty('name') && data.hasOwnProperty('caption') && data.hasOwnProperty('value') && (data.hasOwnProperty('opts') && data.opts.length && data.opts.length === pkgs.length)) {
			var row = optTbl.insertRow(-1);
			row.caption = data.caption;
			row.isChecked = data.isChecked || false;
			row.onUseFees = data.onUseFees || false;
			row.isFree = data.isFree || false;
			row.txtExtra = data.txtExtra || false;
			row.requirement = data.requirement || false;
			row.usePromo = (data.hasOwnProperty('usePromo')) ? data.usePromo : true;
			row.monthlyFees = (data.hasOwnProperty('monthlyFees') && !isNaN(data.monthlyFees)) ? data.monthlyFees : 4.00;
			row.monthlyFeesAlt = (data.hasOwnProperty('monthlyFeesAlt') && !isNaN(data.monthlyFeesAlt)) ? data.monthlyFeesAlt : 2.00;
			row.packCells = [];
			row.requiredFor = false;
			row.addRequiredFor = _addRequiredFor;
			row.removeRequiredFor = _removeRequiredFor;
			
			// Ajoute la cellule de description (première cellule de la ligne avec les checkbox, le label et le lien)
			var c = row.insertCell(0);
			c.className = 'option-box';
				var h = '<label for="' + data.id + '">';
				h += 		'<input type="checkbox" id="' + data.id + '" name="' + data.name + '" value="' + data.value + '"' + ((row.isChecked || row.onUseFees || (row.isFree && !row.requirement)) ? ' checked="checked"' : '') + ((row.onUseFees || (row.isFree && !row.requirement)) ? ' style="visibility: hidden;"' : '') + ' />';
				h +=		'<a class="remoteLoad" href="' + optionsListOverlay + '?lang=' + langURL + '&amp;opt=' + data.id + '">' + _list_.dict.details + '</a>';
				h +=		data.caption;
				h +=	'</label>';
			c.innerHTML = h;
			// Récupère le checkbox
			row.chk = c.getElementsByTagName('input')[0];
			// Récupère le label
			row.lbl = c.getElementsByTagName('label')[0];

			// Indique si le checkbox doit être désactivé (si l'option est payable à l'utilisation)
			if(row.onUseFees) row.chk.disabled = true;

			// Gestion du click pour le checkbox
			YU.Event.addListener(row.chk, 'click', _optionsChange);

			// Pour tous les options qui ne sont pas payable à l'utilisation, ajoute un mouseover et un mouseout pour changer la couleur du label
			if(!(row.onUseFees || (row.isFree && !row.requirement))) {
				YU.Event.addListener(row.lbl, 'mouseover', function() {row.className = 'hover';});
				YU.Event.addListener(row.lbl, 'mouseout', function() {row.className = '';});
			}
						
			// Boucle pour ajouter les cellule de chaque package
			for(var i = 0; i<data.opts.length; i+=1) {
				var c = row.insertCell(i+1);
				var txt = '';
				if(row.isChecked) { // Option sélectionné
					if(row.onUseFees) { // Payable à l'utilisation
						txt = formatCurrency(row.onUseFees);
					} else if (data.opts[i].isIncluded) { // Inclus
						txt = _list_.dict.included;
					} else if (row.isFree) { // Gratuit
						if (data.id == 1002){//pour la ddcjmcjmc
							txt = _list_.dict.NotPerUnit
						}else{
							txt = _list_.dict.free
						}
						//txt = _list_.dict.free
						
					} else if (!row.usePromo || isFirst(row,i)) { // Est la première option
						// thatList.packages[j].runningTotal += opt.monthlyFees;
						txt = formatCurrency(row.monthlyFees);
					} else { // N'est pas la première option
						// thatList.packages[j].runningTotal += opt.monthlyFeesAlt;
						txt = formatCurrency(row.monthlyFeesAlt);
					}
				} else { // Option non sélectionné

					if(row.onUseFees) { // Payable à l'utilisation
						txt = formatCurrency(row.onUseFees);
					} else if (data.opts[i].isIncluded) { // inclus
						txt = _list_.dict.included
					} else if (row.isFree) { // Gratuit
						
						if (data.id == 1002){//pour la ddcjmcjmc
							txt = _list_.dict.NotPerUnit
						}else{
							txt = _list_.dict.free
						}
						//txt = _list_.dict.free
					} else { //Défaut
						txt = '-';
					}
				}

				// Si l'option à un extra text, ajoute le text
				if(row.txtExtra) {
					txt += ' ' + row.txtExtra;
				}
				c.isIncluded = data.opts[i].isIncluded || false;
				c.innerHTML = txt;
				row.packCells.push(c);
			}
			rows[data.id] = row;
		} else {
			throw 'SO_optionList :: addRow - Invalide data format!';
		}
		
	};

	var _renderTable = function() {
		// Prépare le header du table
		var h = optTbl.createTHead();
		// Ajoute une ligne dans le head
		var r = h.insertRow(-1);
		// Ajoute une cellule vide au début
		var c = r.insertCell(0);
		c.innerHTML = '&nbsp;';
		c.className = 'emptyCell';

		// Ajoute une cellul pour chaque package contenant le titre et le prix du package
		for(i = 0; pkgs[i]; i++) {
			var c = r.insertCell(i+1);
			c.innerHTML = '<strong>' + pkgs[i].headCaption + '</strong>'; //<br />' + formatCurrency(pkgs[i].packPrice);
		}

		// Prépare le footer du table
		var f = optTbl.createTFoot();
		//Ajoute une ligne dans le footer
		var r = f.insertRow(-1);
		// Ajoute la cellul contenant le mot Total
		var c = r.insertCell(0);
		c.innerHTML = '<strong>Total</strong>';
		c.className = 'emptyCell';

		// Ajoute une cellule pour chaque package contenant le runningTotal du package
		for(i = 0; pkgs[i]; i++) {
			c = r.insertCell(i+1);
			c.innerHTML = formatCurrency(pkgs[i].runningTotal(), true);
			pkgs[i].footCell = c;
		}
		
				
		// Affiche le table
		wrapper.innerHTML = ''; //Supprime le HTML du wrapper
		wrapper.appendChild(optTbl);
		wrapper.className = '';
		wrapper.style.display = 'block';
		wrapper.style.visibility = 'visible';
		
		// Initialise les overlays de la page
		window.OVERLAY_LATE_INIT = false;
		scriptInit();
		//var optOverlay = new VIDEOTRON.widget.remoteLoad({root: wrapper});
		initVideotronScript();
	}
	
	var _updateTable = function() {
	    for (var opt in rows) {
	        if (rows.hasOwnProperty(opt)) {
				var r = rows[opt];
				// Boucle pour ajouter les cellule de chaque package
				for(var i = 0; pkgs[i]; i+=1) {
					var txt = '';
					if(r.isChecked) { // Option sélectionné
						
						if(r.onUseFees) { // Payable à l'utilisation
							txt = formatCurrency(r.onUseFees);
						} else if (r.packCells[i].isIncluded) { // Inclus
							txt = _list_.dict.included;
						} else if (r.isFree) { // Gratuit
							if ( r.caption == _list_.dict.CaptionOption_1002){//pour la ddcjmcjmc
								txt = _list_.dict.NotPerUnit
							}else{
								txt = _list_.dict.free
							}
							//patch pour SO245227 (Ligne Option - 2iemme colonne on ne peu pas faire le calcule du premier a 4... c'st toujours a 2)
						} else if (!r.usePromo || (isFirst(r,i) && pkgs[i].index != LIGNE_OPTIONS)) { // Utilise un coût fixe par mois ou est la première option
							txt = formatCurrency(r.monthlyFees);
						} else { // N'est pas la première option
							txt = formatCurrency(r.monthlyFeesAlt);
						}
					} else { // Option non sélectionné
						if(r.onUseFees) { // Payable à l'utilisation
							txt = formatCurrency(r.onUseFees);
						} else if (r.packCells[i].isIncluded) { // inclus
							txt = _list_.dict.included
						} else if (r.isFree) { // Gratuit
							//txt = r.caption
							//for(var k in r) alert(k+":"+r[k]);
							if ( r.caption == _list_.dict.CaptionOption_1002){//pour la ddcjmcjmc
								txt = _list_.dict.NotPerUnit
							}else{
								txt = _list_.dict.free
							}
							
						} else { //Défaut
							txt = '-';
						}
						
					
					}
					// Si l'option à un extra text, ajoute le text
					if(r.txtExtra) {
						txt += ' ' + r.txtExtra;
					}
					
					r.packCells[i].innerHTML = txt;
				}
			}
		}
		for(var i=0; pkgs[i]; i+=1) pkgs[i].footCell.innerHTML = formatCurrency(pkgs[i].runningTotal(), true);

	}

	var _addRequiredFor = function(r, optId) {
		// S'il y a déjà des éléments en référence
		if(typeof r.requiredFor != 'boolean') {
			var found = false;
			// Boucle dans les référence pour voir si l'option n'existe pas déjà
			for(var i=0; i<r.requiredFor.length; i+=1) {
				if(r.requiredFor[i] == optId) {
					found = true;
					break;
				}
			}
			// Si l'élément n'a pas été trouvé, il est ajouté
			if(!found) {
				r.requiredFor.push(optId);
			}
		} else {
			r.requiredFor = [optId];
		}
	};
	
	var _removeRequiredFor = function(r, optId) {
		if(typeof r.requiredFor == 'boolean') return false;
		if(r.requiredFor.length == 1) {
			if(r.requiredFor[0] == optId) {
				r.requiredFor = false;
				rows[optId].chk.disabled = false;
				return true;
			} else {
				return false;
			}
		} else {
			var newReq = [];
			var found = false;
			// Boucle dans les référence pour voir si l'option existe
			for(var i=0; i<r.requiredFor.length; i+=1) {
				// Si l'option courante n'est pas le même que optId, ajoute au nouveau array d'options
				if(r.requiredFor[i] != optId) {
					newReq.push(r.requiredFor[i]);
				} else {
					// Indique que l'option a été trouvé et sera retiré
					found=true;
				}
			}
			// Conserve le nouveau array avec le optId en moins
			r.requiredFor = newReq;
			return found;
		}
	};
	
	/**
	 * Event : Événement lié au click sur les checkbox des options
	 */
	var _optionsChange = function() {
		var r = rows[this.id];
		r.isChecked = this.checked;
		
		if(!r.requirement) {
			_updateTable();
		} else {
			// l'option n'est plus sélectionné.
			if(!r.isChecked) {
				// Boucle pour supprimer les dépenses et réactiver les options qui étaient requises
				for(var i=0; i<r.requirement.length; i+=1) {
					var reqFor = rows[r.requirement[i]];
					if(reqFor) {
						reqFor.removeRequiredFor(reqFor, this.id);
						if(!reqFor.requiredFor) reqFor.chk.disabled = false;
					}
				}
				_updateTable();
				
			} else { // L'option est sélection, doit vérifier les dépendences
				var reqList = [];
				for(var i=0; i<r.requirement.length; i+=1) {
					var curOpt = rows[r.requirement[i]];
					if(!curOpt.isChecked) {
						curOpt.chk.disabled = false;
					}
					reqList.push(curOpt);
					
				}
				if(reqList.length) {
					showConfirmServices(r, reqList, _updateTable);
				}
			}
						
		}
		
		return;

	}
	/*** END EVENT optionsChange ***/
	
	/**
	 * Fonction utilisé pour déterminer si l'option est la première option payable mensuellement qui est sélectionné
	 *
	 * @param {r Object} Objet ROW. Élément à vérifier
	 * @param {p Integer} Index du package courrant. Permet de ne pas tenir compte des options incluses dans un package
	 *
	 * @return {Boolean}
	 */
	var isFirst = function(r, p) {
		/*
			Cette méthode permet de déterminer si l'otion est la première choisi en fonction des règles suivantes :
			1- La première choisi dans le package courant utilisant les promos
			2- Ne tient pas compte des options gratuites, incluses ou payable à l'utilisation
		*/
		
		// Boucle dans les options du package courant
	    for (var opt in rows) {
	        if (rows.hasOwnProperty(opt)) {
				opt = rows[opt];
				// Si l'option est l'option courrante
				if(opt === r) {
					if(r.isChecked && !r.packCells[p].isIncluded && !r.isFree && !r.onUseFees && r.usePromo) {
						return true;
					}
				} else if(opt.isChecked && !opt.packCells[p].isIncluded && !opt.isFree && !opt.onUseFees && opt.usePromo) {
					return false;
				}
	        }
	    }

		return true;
	};
	/*** END FUNCTION isFirst ***/
	
	/**
	 * Fonction utilisé pour formaté le prix correctement en fonction la langue
	 * @return literal string (formated)
	 */
	var formatCurrency = function (price) {
		//Défini la langue et les séparateurs (millier et décimal)
		var lg = document.documentElement.lang;
		var tsep = (lg == 'fr') ? ' ' : ',';
		var dsep = (lg == 'fr') ? ',' : '.';
		//Supprime les $ et , des prix fournis
		num = price.toString().replace(/\$|\,/g,'');
		//Si la valeur résultante n'est pas un nombre, retourne la valeur reçus
		if(isNaN(num)) return price;
		
		//Vérifie si la valeur est signé (négatif)
		sign = (num == (num = Math.abs(num)));
		//Arrodis la vlaeur reçus
		num = Math.floor(num*100+0.50000000001);
		//Récupère les cents dans une variable à part (2 décimal seulement)
		cents = ('0' + (num%100));
		cents = cents.substring(cents.length-2);
		
		//Récupère les dolars seulement
		num = Math.floor(num/100).toString();
		//Boucle pour séparer en groupe de 4 didgit
		for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
			num = num.substring(0,num.length-(4*i+3))+tsep+num.substring(num.length-(4*i+3));
		
		if(arguments[1]) { // Si true, indique un formatage de type "Price"
			return '<div style="width: 6.5em; margin: 0 auto;"><div class="price">' + ((lg == 'fr') ? '' : '<sup class="unit">$</sup>') + num + '<sup>' + dsep + cents + ((lg == 'fr') ? '$' : '') + '</sup><span class="slash">/' + ((lg == 'fr') ? 'mois' : 'month') + '<a class="anchor-0" title="Certain conditions apply" href="#note-0">*</a></span></div></div>';
		} else { // Retourne le résultat comme un string formaté
			return (((sign)?'':'-') + ((lg == 'fr') ? '' : '$') + num + dsep + cents + ((lg == 'fr') ? ' $' : ''));
		}
	}
	/*** END FUNCTION formatCurrency ***/
	
	return {
		addPackage: function (inf) {
			return _addPackage(inf);
		},
		addRow: function (opts) {
			return _addRow(opts);
		},
		packages: pkgs,
		render: function() {
			_renderTable();
		},
		update: function() {
			_updateTable();
		}
	};
}

var confirmServices;

function initConfirmServices() {
	
	confirmServices = 
		new YAHOO.widget.SimpleDialog("simpledialog1", 
				 { width: "40em",
				   fixedcenter: true,
				   modal: true,
				   visible: false,
				   draggable: false,
				   close: true,
				   text: "",
				   constraintoviewport: true
				 } );
	
	
	var hadleShow = function() {
		confirmServices.show();
	};

	confirmServices.setHeader("");
	
	// Render the Dialog
	confirmServices.render(document.body);

}
YAHOO.util.Event.addListener(window, "load", initConfirmServices);

function showConfirmServices(curOpt, reqOpts, fn) {
	var bMustShow = false;
	var lg = document.documentElement.lang;
	// Récupère la liste des options requisent et l'option courante dans les objets gestions
	handleConfirmServicesYes.obj = handleConfirmServicesNo.obj = {reqList: reqOpts, target: curOpt, func: fn};
	// Prépare le texte d'affichage du dialogue
	var txt = '<strong>' + curOpt.caption + '</strong><br /><br />';
	if(lg == 'fr') {
		txt += ((reqOpts.length > 1) ? 'Ce service nécessite l\'abonnement aux services suivants :' : 'Ce service nécessite l\'abonnement au service suivant :') + '<br /><br /><ul>';
		var btn = {Yes:'Oui', No:'Non'};
	} else {
		txt += ((reqOpts.length > 1) ? 'This service requires to subscribe to the following ones:' : 'This service requires to subscribe to the following one:') + '<br /><br /><ul>';
		var btn = {Yes:'Yes', No:'No'};
	}
	// Ajoute la liste des services requis au texte
	for(var i=0; i<reqOpts.length; i+=1){
		if(!reqOpts[i].isChecked) bMustShow = true;
		txt += '<li>' + reqOpts[i].caption + '</li>';
	}
	txt += '</ul>';
	// Assigne le texte, défini les bouttons et render le dialogue
	confirmServices.cfg.setProperty('text', txt);
    confirmServices.cfg.setProperty('buttons', [ { text:btn.Yes, handler:handleConfirmServicesYes, isDefault:true }, { text:btn.No,  handler:handleConfirmServicesNo } ]);
	confirmServices.render(document.body);
	
	// Affiche la boite de dialogue
	if(bMustShow) confirmServices.show();
	else handleConfirmServicesYes.fn(confirmServices, handleConfirmServicesYes.obj);
}

// Gestion du bouton Oui dans le dialogue
var handleConfirmServicesYes = {
	fn: function() {
			// Ferme le dialogue
			confirmServices.hide();
			// Récupère la liste des objets prérequis
			opts = arguments[1].reqList;
			curOpt = arguments[1].target;
			// Boucle pour checker et désactiver les options requisent
			for(var i=0; i<opts.length; i+=1) {
				opts[i].addRequiredFor(opts[i], curOpt.chk.id);
				opts[i].chk.checked = opts[i].isChecked = true;
				opts[i].chk.disabled = true;
			}
			// Mets à jour le tableau
			arguments[1].func();
		},
	obj: {} // Reçois un objet contenant la liste des options requisent pour l'option courrante et l'option cliqué
};

// Gestion du bouton Non dans le dialogue
var handleConfirmServicesNo = {
	fn: function() {
			// Ferme le dialogue
			confirmServices.hide();
			// Récupère la liste des objets prérequis
			opts = arguments[1].reqList;
			curOpt = arguments[1].target;
			// Boucle pour checker et désactiver les options requisent
			for(var i=0; i<opts.length; i+=1) {
				opts[i].removeRequiredFor(opts[i], curOpt.chk.id);
				opts[i].chk.disabled = (opts[i].requiredFor !== false);
			}
			// Uncheck l'option choisi, puisque l'utilisateur a décidé de ne pas prendre les options requises pour l'option
			curOpt.isChecked = curOpt.chk.checked = false;

			// Mets à jour le tableau
			arguments[1].func();
		},
	obj: {} // Reçois un objet contenant la liste des options requisent pour l'option courrante et l'option cliqué
};


function old2() {
	/* VIDEOTRON.widget.SO_optionList = function(elem) {
	
		var that = this;
	
		if(document.documentElement.lang == 'fr') {
			var dict = {
				free: 'Gratuit',
				included : 'Inclus'
			};
		} else {
			var dict = {
				free: 'FREE',
				included : 'Included'
			};
		}	
	
		if (typeof elem === "undefined" || !elem) {
			elem = 'options-wrapper';
		}
		// Récupère le wrapper
		var wrapper = (function () {
			var w = YAHOO.util.Dom.get(elem);
			if((typeof w !== "undefined" && w)) return w;
			throw 'SO_optionList.wrapper :: ' + elem + ' not found!';
		})();
		
		// Création du table pour afficher les options.
		var optTbl = (function() {
			var t = document.createElement('table');
			t.id = 'tbl-' + wrapper.id;
			t.className = 'clear';
			return t;
		})();
		
		var _packages = {};
		var _rows = {};
		
		var Option = function(opt) {
			
			var _opt_ = this;
	
			var _conf = {
				id: '',
				name: '',
				value: '',
				caption: '',
				checked: false,
				isIncluded: false,
				isFree: false,
				monthlyFees: 4.00,
				monthlyFeesAlt: 2.00,
				onUseFees: false,
				requirement: false,
				txtExtra: '',
				requiredFor: false
			};
	
	        // Override defaults with user config values
	        if (opt) {
	            for (var key in opt) {
	                if (opt.hasOwnProperty(key)) {
	                    _conf[key] = opt[key];
	                }
	            }
	        }
		
			var _cell;
			
			return {
				conf: function (idx) {
					if(!idx) return _conf;
					else if(!_conf[idx]) return;
					else return _conf[idx];
				},
				createCell: function (tblRow, pkgIndex) {
					_cell = tblRow.insertCell(pkgIndex);
					return _cell;
				},
				cell: (function () {return _cell;})(),
				getText: function () {
					var c = _opt_._conf;
					if(_rows[c.id].checkBox.checked) {
						if(c.onUseFees) {
							return formatCurrency(c.onUseFees);
						} else if (c.isIncluded) {
							return dict.included;
						} else if (c.isFree) { // Gratuit
							return dict.free;
						} else if (_opt_.isFirst()) { // Est la première option
							// thatList.packages[j].runningTotal += opt.monthlyFees;
							return formatCurrency(c.monthlyFees);
						} else { // N'est pas la première option
							// thatList.packages[j].runningTotal += opt.monthlyFeesAlt;
							return formatCurrency(c.monthlyFeesAlt);
						}
						
					} else {
						if(c.onUseFees) { // Payable à l'utilisation
							return formatCurrency(c.onUseFees);
						} else if (opt.isIncluded) { // inclus
							return dict.included;
						} else if (c.isFree) { // Gratuit
							return dict.free;
						} else { //Défaut
							return '-';
						}
					
					}
				}
			}; 
		};
		
		var Package = function (cfgs) {
			var _pkg_ = this;
			var _conf = {
				headCaption: '',
				packagePrice: 0.00
			};
			var _runningTotal = function () {
	            for (var o in _options) {
	                if (_options.hasOwnProperty(o)) {
	                    
	                }
	            }
			};
			
			var _options = {};
			
			return {
				headCaption: function () {return _conf.headCaption;},
				packagePrice: function() {return _conf.packagePrice;},
				addOption: function(opt) {
					_options[opt.id] = new Option(opt);
					return _options[opt.id];
				},
			};
		};
		
		return {
			addPackage : function (id, cfg) {
				_packages[id] = new Package(cfg);
				_packagesList.push(id);
				return _packages[id];
			},
			addRow : function(rowInfo, pkgsData) {
			
			},
		};	
	} */
}

function old_Videotron_OptionList() {
	/**
	 * Collection d'objets so_options : Représente la liste complète des options
	 * Crée un objet de liste d'option
	 * @param {String|HTMLElement} elem Le ID ou une référence à l'élément qui doit contenir la liste (Le wrapper)
	 * @requires YAHOO.util.Dom
	 * @requires YAHOO.util.Config
	 * @return un objet SO_optionList
	 */
	VIDEOTRON.widget.SO_optionList = function(elem) {
	
		var thatList = this;
		
		if (typeof elem === "undefined" || !elem) {
			elem = 'options-wrapper';
		}
		// Récupère le wrapper
		this.wrapper = YAHOO.util.Dom.get(elem);
		if (typeof this.wrapper === "undefined" || !this.wrapper) {
			throw 'SO_optionList.wrapper :: ' + elem + ' not found!';
		}

		// Création d'un table pour recevoir le contenue.
		this.table = document.createElement('table');
		this.table.id = 'tbl-' + this.wrapper.id;
		this.table.className = 'clear';

		/*  Collection d'objet so_option : Représente une colonne d'options (un forfaits, i.e.: ligne de base, ligne avec option, etc) */
		this.packages = [];

		/**
		 * Fonction utilisé pour supprimer toutes les lignes du table pour reconstruire le résultat
		 * @Private
		 */
		var resetTable = function(tbl) {
			if(tbl) {
				tbl.deleteTHead();
				tbl.deleteTFoot();
				while (tbl.rows.length) {
					tbl.deleteRow(-1);
				}
			}
		};
		/*** END PRIVATE FUNCTION resetTable ***/

		
		/**
		 * Ajoute un package (une colonne) à la liste
		 * @param {Object} pkg Un objet de type VIDEOTRON.widget.SO_options
		 * @return un objet SO_options
		 */
		this.addPackage = function(pkg) {
			var pack = new VIDEOTRON.widget.SO_optionList.prototype.SO_options(pkg);
			pack.parent = this;
			thatList.packages.push(pack);
			return pack;
		};

		/**
		 * Supprime le contenue du wrapper
		 */
		this.cleanup = function() {
			if(thatList.wrapper) {
				thatList.wrapper.innerHTML = ''; //Supprime le HTML du wrapper
				//Overwrite la fonction cleanup par la fonction resetTable
				resetTable(this.table);
			}
		};
		/*** END FUNCTION cleanup ***/

		this.isRendering = false;
		
		/**
		 * Fonction utilisé pour construire le tableau à partir des options et package fournis.
		 * La fonction est appellé à chaque clique sur les options pour mettre à jour le tableau
		 * de façon dynamique.
		 */
		this.render = function() {
			thatList.isRendering = true;
			var i, j, opt, myHead, myBody, myFoot, myRow, myCell, myText, myCellText, addExtra;
			// Cache le contenu actuel du wrapper (accessible sans javascript)
			// Ou vide le tableau
			thatList.cleanup();

			// Reset le runningTotal de chaque forfaits
			for(j = 0; this.packages[j]; j++) {
				thatList.packages[j].runningTotal = thatList.packages[j].packagePrice;
			}
			
			// Ajoute les lignes d'options
			for(i = 0; thatList.packages[0].options[i]; i+=1) {
				// Ajoute un row au tableau
				myRow = thatList.table.insertRow(-1);
				addExtra = false;
				
				// Ajoute la cellule avec le checkbox, le labe et le lien détail
				myCell = myRow.insertCell(0);
				myCell.className = 'option-box';
				myCell.packIndex = i;
				myCell.appendChild(thatList.packages[0].options[i].captionLabel());
				
				// Ajoute une cellule pour chaque package avec la valeur appropiée
				for(j = 0; thatList.packages[j]; j++) {
					opt = thatList.packages[j].options[i];
					myCell = myRow.insertCell(j+1);
					
					if(opt.checked) { // Option sélectionné
						
						if(opt.onUseFees) { // Payable à l'utilisation
							myText = formatCurrency(opt.onUseFees);
						} else if (opt.isIncluded) { // Inclus
							myText = 'Inclus'; ////////// :: A TRADUIRE AUSSI
						} else if (opt.isFree) { // Gratuit
							myText = 'Gratuit'; ////////// :: A TRADUIRE AUSSI
						} else if (opt.isFirst()) { // Est la première option
							thatList.packages[j].runningTotal += opt.monthlyFees;
							myText = formatCurrency(opt.monthlyFees);
						} else { // N'est pas la première option
							thatList.packages[j].runningTotal += opt.monthlyFeesAlt;
							myText = formatCurrency(opt.monthlyFeesAlt);
						}
					
					} else { // Option non sélectionné
						
						if(opt.onUseFees) { // Payable à l'utilisation
							myText = formatCurrency(opt.onUseFees);
						} else if (opt.isIncluded) { // inclus
							myText = 'InclusE'; ////////// :: A TRADUIRE AUSSI
						} else if (opt.isFree) { // Gratuit
							myText = 'GratuitE'; ////////// :: A TRADUIRE AUSSI
						} else { //Défaut
							myText = '-';
						}
					
					}
					// Si l'option à un extra text, ajoute le text
					if(opt.txtExtra) {
						// addExtra = true;
						// myCell.title = opt.txtExtra;
						myText += ' ' + opt.txtExtra;
					}
					myCellText = document.createTextNode(myText);
					myCell.appendChild(myCellText);
					/*if(opt.txtExtra) {
						myCell.appendChild(document.createElement('br'));
						myCell.appendChild(document.createTextNode(opt.txtExtra));
					}*/
				}
				if(addExtra) {
					myRow.className = 'extra-info';
				}
				
			} // -- END FOR PACKAGES
	
			// Crée le header du table
			myHead = thatList.table.createTHead();
			// Ajoute une ligne dans le head
			myRow = myHead.insertRow(-1);
			// Ajoute une cellule vide au début
			myCell = myRow.insertCell(0);
			myCell.innerHTML = '&nbsp;';
			myCell.className = 'emptyCell';

			// Ajoute une cellul pour chaque package contenant le titre et le prix du package
			for(i = 0; thatList.packages[i]; i++) {
				myCell = myRow.insertCell(i+1);
				myCellText = document.createElement('strong');
				myCellText.appendChild(document.createTextNode(thatList.packages[i].headCaption));
				myCell.appendChild(myCellText);
				myCell.appendChild(document.createElement('br'));
				myCell.appendChild(document.createTextNode(formatCurrency(thatList.packages[i].headPrice)));
			}

			// Crée le footer du table
			myFoot = thatList.table.createTFoot();
			//Ajoute une ligne dans le footer
			myRow = myFoot.insertRow(-1);
			// Ajoute la cellul contenant le mot Total
			myCell = myRow.insertCell(0);
			myCell.innerHTML = '<strong>Total</strong>';
			myCell.className = 'emptyCell';

			// Ajoute une cellule pour chaque package contenant le runningTotal du package
			for(i = 0; thatList.packages[i]; i++) {
				myCell = myRow.insertCell(i+1);
				myCellText = document.createElement('strong');
				myCellText.appendChild(document.createTextNode(formatCurrency(thatList.packages[i].runningTotal)));
				myCell.appendChild(myCellText);
			}
			
			thatList.wrapper.appendChild(thatList.table);
			//initRemoteLoad();
			generateTooltipsForTagName('extra-info', 'tr', true);			

			thatList.isRendering = false;
		};
		/*** END FUNCTION render ***/

		/**
		 * Fonction utilisé pour mettre à jour le tableau à partir des options et package fournis.
		 * La fonction est appellé à chaque clique sur les options pour mettre à jour le tableau
		 * de façon dynamique.
		 */
		this.updateTable = function() {
			thatList.isRendering = true;
			var i, j, opt, myHead, myBody, myFoot, myRow, myCell, myText, myCellText, addExtra;
			if(document.documentElement.lang == 'fr') {
				var dict = {
					free: 'Gratuit',
					included : 'Inclus'
				};
			} else {
				var dict = {
					free: 'FREE',
					included : 'Included'
				};
			}
			// Reset le runningTotal de chaque forfaits
			for(j = 0; thatList.packages[j]; j++) {
				this.packages[j].runningTotal = thatList.packages[j].packagePrice;
			}

			for(i = 1; i < thatList.table.rows.length-1; i+=1){
					
				var tds = thatList.table.rows[i].getElementsByTagName('td');

				for(j=1;j<tds.length; j+=1) {
					//Supprime tous les éléments de la cellule
					while (tds[j].firstChild) {
						tds[j].removeChild(tds[j].firstChild);
					}
					// Ajuste le contenue des cellules pour chaque package avec la valeur appropiée
					opt = thatList.packages[j-1].options[tds[0].packIndex];
					myCell = tds[j];
					
					if(opt.checked) { // Option sélectionné
						if(opt.requiredFor && j==1) {
							thatList.table.rows[i].TooltipsText = thatList.getRequiredForInfo(opt);
							thatList.table.rows[i].className = 'extra-info';
						} else if(j==1) {
							if(typeof thatList.table.rows[i].tooltip != 'undefined') thatList.table.rows[i].tooltip.disabled = true;
							thatList.table.rows[i].TooltipsText = '';
							thatList.table.rows[i].className = '';
						}
						
						if(opt.onUseFees) { // Payable à l'utilisation
							myText = formatCurrency(opt.onUseFees);
						} else if (opt.isIncluded) { // Inclus
							myText = dict.included;
						} else if (opt.isFree) { // Gratuit
							myText = dict.free;
						} else if (opt.isFirst()) { // Est la première option
							thatList.packages[j-1].runningTotal += opt.monthlyFees;
							myText = formatCurrency(opt.monthlyFees);
						} else { // N'est pas la première option
							thatList.packages[j-1].runningTotal += opt.monthlyFeesAlt;
							myText = formatCurrency(opt.monthlyFeesAlt);
						}
					
					} else { // Option non sélectionné
						if(j==1) {
							thatList.table.rows[i].TooltipsText = '';
							thatList.table.rows[i].className = '';
						}
						if(opt.onUseFees) { // Payable à l'utilisation
							myText = formatCurrency(opt.onUseFees);
						} else if (opt.isIncluded) { // inclus
							myText = dict.included; ////////// :: A TRADUIRE AUSSI
						} else if (opt.isFree) { // Gratuit
							myText = dict.free; ////////// :: A TRADUIRE AUSSI
						} else { //Défaut
							myText = '-';
						}
					
					}
					// Si l'option à un extra text, ajoute le text
					if(opt.txtExtra) {
						addExtra = true;
						myCell.title = opt.txtExtra;
						myText += ' ' + opt.txtExtra;
					}
					myCellText = document.createTextNode(myText);
					myCell.appendChild(myCellText);
					
					/*if(opt.txtExtra) {
						myCell.appendChild(document.createElement('br'));
						myCell.appendChild(document.createTextNode(opt.txtExtra));
					}*/

				}
			}

			var tds = thatList.table.rows[thatList.table.rows.length-1].getElementsByTagName('td');
			// Ajuste le runningTotal de chaque package
			for(i = 1; i<tds.length; i+=1) {
				myCell = tds[i];
				//Supprime tous les éléments de la cellule
				while (myCell.firstChild) {
					myCell.removeChild(myCell.firstChild);
				}
				myCellText = document.createElement('strong');
				myCellText.appendChild(document.createTextNode(formatCurrency(thatList.packages[i-1].runningTotal)));
				myCell.appendChild(myCellText);
			}
			
			generateTooltipsForTagName('extra-info', 'tr', true);
			
			thatList.isRendering = false;
			return;
			
			
		};
		/*** END FUNCTION updateTable ***/
		
		this.getRequiredForInfo = function(opt) {
			var lg = document.documentElement.lang;
			// Prépare le texte d'affichage du dialogue
			var txt = '<strong>' + opt.caption + '</strong><br />';
			if(lg == 'fr') {
				txt += ((opt.requiredFor.length > 1) ? 'Ce service est un pré-requis aux services suivants :' : 'Ce service est un pré-requis au service suivant :') + '<br /><ul>';
			} else {
				txt += ((reqOpts.length > 1) ? 'This service is a requirement for the following services:' : 'This service is a requirement for the following service:') + '<br /><ul>';
			}
			// Ajoute la liste des services requis au texte
			for(var i=0; i<opt.requiredFor.length; i+=1){
				txt += '<li>' + opt.parentPkg.getOptionById(opt.requiredFor[i]).caption + '</li>';
			}
			txt += '</ul>';
			console.debug(txt);
			return txt;
		}
		return thatList;
	};

	
	/**
	 * Collection d'objet so_option : Représente une colonne d'options (un forfaits, i.e.: ligne de base, ligne avec option, etc)
	 * @param {Object} opts Un objet contenant les informations d'initialisation de la collection
	 * @return un objet SO_options
	 */
	VIDEOTRON.widget.SO_optionList.prototype.SO_options = function(opts) {
		/* opts = 
		  {
			@required  headCaption: '', // Titre qui s'affiche dans le header de la colonne
			@required  headPrice: '', // Prix qui s'affiche dans le header de la colonne
			packagePrice: false // Prix du package si applicable (prix fix représentant toutes les options inclus ou gratuit applicable au package (i.e.: Lige résidentiel avec options)
		  }
		 */

		var key;
		var thatOptions = this;
		this.headCaption = '';
		this.headPrice = '';
		this.packagePrice = 0.00;
		
		// Initialise le running total à 0
		this.runningTotal = 0.00;
		
        // Override defaults with user config values
        if (opts) {
            for (key in opts) {
                if (opts.hasOwnProperty(key)) {
                    this[key] = opts[key];
                }
            }
        }
		
		/**
		 * Fonction utilisé pour ajouté une option à la collection
		 * @param {Object} opt Un objet contenant les informations d'initialisation de l'objet
		 * @return un objet SO_options
		 */
		this.addOption = function(opt) {
			var oOpt = new VIDEOTRON.widget.SO_optionList.prototype.SO_options.prototype.SO_option(opt);
			oOpt.parentPkg = thatOptions;
			thatOptions.options.push(oOpt);
		};
		
		/*** END FUNCTION addOption ***/

		this.getOptionById = function(oId) {
			for(var i=0; i<thatOptions.options.length; i+=1) {
				if(thatOptions.options[i].id == oId) return thatOptions.options[i];
			}
			return false;
		}
		
		this.options = [];
		
		return thatOptions;
	};
	/*** END OBJECT SO_options ***/
	

	/**
	 * Objet so_option : Représente une option (une ligne dans le tableau) (i.e.: Afficheur, Messagerie vocal, etc)
	 * @param {Object} opt Un objet contenant les informations d'initialisation de l'option
	 * @return un objet SO_options
	 */
	VIDEOTRON.widget.SO_optionList.prototype.SO_options.prototype.SO_option = function(opt) {
		/* opt = 
		  {
			@required  id: '', // Id à donner au checkbox. Permet aussi de relié les mêmes options d'un forfaits à l'autre
			@required  name: '', // name à donner au checkbox
			@required  value: '', // Value retournée par le checkbox lors du submit
			@required  caption: '', // Titre de l'option qui apparait dans la première colone du tableau et afficher dans un tag label
			checked: false, //Indique si l'option est coché ou pas
			isIncluded: false, // Indique si l'option est inclus avec le forfait qui lui est attaché: Cette option overwrite les frais mensuel et le gratuit
			isFree: false, // Indique si l'option est gratuite avec le forfait qui lui est attaché
			monthlyFees: 4.00, // Indique le coûts de l'option mensuel
			monthlyFeesAlt: 2.00, // Indique coûts de l'option mensuel lorsqu'elle est jumélée à d'autre option
			onUseFees: false, // Indique le coûts à l'utilisation: Cette option overwrite les frais mensuel, le free et le inclus
			requirement: false // Reçois les objet de dépendance pour les prérequis
			txtExtrat: '' // Reçois un texte supplémentaire à mettre à côté des prix pour les options payable à l'utilisation ou gratuite avec préreqis
		  }
		*/
		var that = this;
		this.id = '';
		this.name = '';
		this.value = '';
		this.caption = '';
		this.checked = false;
		this.isIncluded = false;
		this.isFree = false;
		this.monthlyFees = 4.00;
		this.monthlyFeesAlt = 2.00;
		this.onUseFees = false;
		this.requirement = false;
		this.txtExtra = ''
		this.requiredFor = false;

		var key;
        // Override defaults with user config values
        if (opt) {
            for (key in opt) {
                if (opt.hasOwnProperty(key)) {
                    this[key] = opt[key];
                }
            }
        }
		
		this.myLabel = false;
		
		/**
		 * Event : Événement lié au click sur les checkbox des options
		 */
		this.optionsChange = function() {
			if(!this.optElem.parentPkg.parent.isRendering) {
				this.optElem.checked = this.checked;
				pkgs = this.optElem.parentPkg.parent.packages;
				for(i=1; pkgs[i]; i++) {
					for(j=0; pkgs[i].options[j]; j++) {
						if(pkgs[i].options[j].id == this.optElem.id) {
							pkgs[i].options[j].checked = this.checked;
							break;
						}
					}
				}
				if(!this.optElem.requirement) {
					this.optElem.parentPkg.parent.updateTable();
				} else {
					if(!this.optElem.checked) {
						// Boucle pour checker et désactiver les options requisent
						for(var i=0; i<this.optElem.requirement.length; i+=1) {
							alert('elem' + i);
							opt = that.parentPkg.getOptionById(this.optElem.requirement[i]);
							opt.removeRequiredFor(this.optElem.id);
							if(!opt.requiredFor) opt.checkbox.disabled = false;
						}
						this.optElem.parentPkg.parent.updateTable();
					} else {
						var reqList = [];
						for(var i=0; i<this.optElem.requirement.length; i+=1) {
							var curOpt = that.parentPkg.getOptionById(this.optElem.requirement[i]);
							if(!curOpt.checked) {
								curOpt.checkbox.disabled = false;
							}
							reqList.push(curOpt);
							
						}
						if(reqList.length) {
							showConfirmServices(that, reqList, this.optElem.parentPkg.parent.updateTable);
						}
					}
				}
			}
		}
		/*** END EVENT optionsChange ***/
		
		this.addRequiredFor = function(optId) {
			// S'il y a déjà des éléments en référence
			if(typeof that.requiredFor != 'boolean') {
				var found = false;
				// Boucle dans les référence pour voir si l'option n'existe pas déjà
				for(var i=0; i<that.requiredFor.length; i+=1) {
					if(that.requiredFor[i] == optId) {
						found = true;
						break;
					}
				}
				// Si l'élément n'a pas été trouvé, il est ajouté
				if(!found) {
					that.requiredFor.push(optId);
				}
			} else {
				that.requiredFor = [optId];
			}
		};
		
		this.removeRequiredFor = function(optId) {
			if(typeof that.requiredFor == 'boolean') return false;
			if(that.requiredFor.length == 1) {
				if(that.requiredFor[0] == optId) {
					that.requiredFor = false;
					return true;
				} else {
					return false;
				}
			} else {
				var newReq = [];
				var found = false;
				// Boucle dans les référence pour voir si l'option existe
				for(var i=0; i<that.requiredFor.length; i+=1) {
					// Si l'option courante n'est pas le même que optId, ajoute au nouveau array d'options
					if(that.requiredFor[i] != optId) {
						newReq.push(this.requiredFor[i]);
					} else {
						// Indique que l'option a été trouvé et sera retiré
						found=true;
					}
				}
				// Conserve le nouveau array avec le optId en moins
				that.requiredFor = newReq;
				return found;
			}
		};

		/**
		 * Fonction utilisé pour générer le <label> contenant le checkbox, le caption et le lien details
		 * @return un HTMLObject représentant le code du label généré
		 */
		this.captionLabel = function() {
			if(that.myLabel) return that.myLabel;
			// Gestion des exception du DOM de Internet Explorer
			if(YAHOO.env.ua.ie) {

				// Crée le checkbox
				that.checkbox = document.createElement('<input type="checkbox" id="' + that.id + '" name="' + that.name + '" value="' + that.value + '"' + ((that.checked || that.onUseFees || (that.isFree && !that.requirement)) ? ' checked="checked"' : '') + ((that.onUseFees || (that.isFree && !that.requirement)) ? ' style="visibility: hidden;"' : '') + ' />');
				// Crée le caption du label
				var t = document.createTextNode(that.caption);
				// Crée le label
				var lbl = document.createElement('<label for="' + that.id + '"></label>');
				// Pour les paiement à l'utilisation, désactive le checkbox
				if(that.onUseFees) that.checkbox.disabled = true;

			} else { // Autre browser

				// Crée le label
				var lbl = document.createElement('label');
				lbl.setAttribute('for', that.id);
				//Crée le caption du label
				var t = document.createTextNode(that.caption);

				// Crée le checkbox
				that.checkbox = document.createElement('input');
				that.checkbox.type = 'checkbox';
				that.checkbox.id = that.id;
				that.checkbox.name = that.name;
				that.checkbox.checked = (that.checked) ? 'checked' : '';
				that.checkbox.value = that.value;
				// Pour les paiements à l'utilisation, check, désactive et cache le checkbox, 
				if(that.onUseFees || (that.isFree && !that.requirement)) {
					that.checkbox.checked = true;
					that.checkbox.disabled = true;
					that.checkbox.style.visibility = 'hidden';
				}
				
			
			};

			// Crée le lien détails
			var a = document.createElement('a');
			a.href = "/service/telephonie/services-optionnels/options-overlay-fr.jsp?sopt=" + that.id;
			a.title = "";
			a.className = "remoteLoad";
			a.appendChild(document.createTextNode(((document.documentElement.lang == 'fr') ? 'Détails' : 'Details')));

			// Ajoute le checkbox au label
			lbl.appendChild(that.checkbox);
			// Ajoute le lien au label
			lbl.appendChild(a);
			// Ajoute le caption au label
			lbl.appendChild(t);

			// Indique l'option attaché au checkbox
			that.checkbox.optElem = that;
			// Gestion du click pour le checkbox
			YAHOO.util.Event.addListener(that.checkbox, 'click', that.optionsChange);

			// Pour tous les options qui ne sont pas payable à l'utilisation, ajoute un mouseover et un mouseout pour changer la couleur du label
			if(!(that.onUseFees || (that.isFree && !that.requirement))) {
				YAHOO.util.Event.addListener(lbl, 'mouseover', function() {that.className = 'hover';});
				YAHOO.util.Event.addListener(lbl, 'mouseout', function() {that.className = '';});
			}
			that.myLabel = lbl;

			return that.myLabel;
		};				
		/*** END EVENT captionLabel ***/

		
		/**
		 * Fonction utilisé pour déterminer si l'option est la première option payable mensuellement qui est sélectionné
		 * @return {Boolean}
		 */
		this.isFirst = function() {
			/*
				Cette méthode permet de déterminer si l'otion est la première choisi en fonction des règles suivantes :
				1- La première choisi dans le package courant
				2- Ne tient pas compte des options gratuites, incluses ou payable à l'utilisation
			*/
			
			var i;
			// Boucle dans les options du package courant
			for(i=0; that.parentPkg.options[i]; i++) {
				// Si l'option est l'option courrante 
				if(that.parentPkg.options[i] === that) {
					if(that.checked && !that.isIncluded && !that.isFree && !that.onUseFees) {
						return true;
					}
				} else if(that.parentPkg.options[i].checked && !that.parentPkg.options[i].isIncluded && !that.parentPkg.options[i].isFree && !that.parentPkg.options[i].onUseFees) {
					return false;
				}
			}

			return true;
		};
		/*** END FUNCTION isFirst ***/
		return that;
	};
	/*** END OBJECT SO_options.SO_option ***/


	/**
	 * Fonction utilisé pour formaté le prix correctement en fonction la langue
	 * @return literal string (formated)
	 */
	function formatCurrency(price) {
		//Défini la langue et les séparateurs (millier et décimal)
		var lg = document.documentElement.lang;
		var tsep = (lg == 'fr') ? ' ' : ',';
		var dsep = (lg == 'fr') ? ',' : '.';
		//Supprime les $ et , des prix fournis
		num = price.toString().replace(/\$|\,/g,'');
		//Si la valeur résultante n'est pas un nombre, retourne la valeur reçus
		if(isNaN(num)) return price;
		
		//Vérifie si la valeur est signé (négatif)
		sign = (num == (num = Math.abs(num)));
		//Arrodis la vlaeur reçus
		num = Math.floor(num*100+0.50000000001);
		//Récupère les cents dans une variable à part (2 décimal seulement)
		cents = ('0' + (num%100));
		cents = cents.substring(cents.length-2);
		
		//Récupère les dolars seulement
		num = Math.floor(num/100).toString();
		//Boucle pour séparer en groupe de 4 didgit
		for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
			num = num.substring(0,num.length-(4*i+3))+tsep+num.substring(num.length-(4*i+3));
		return (((sign)?'':'-') + ((lg == 'fr') ? '' : '$') + num + dsep + cents + ((lg == 'fr') ? ' $' : ''));
	}
	/*** END FUNCTION formatCurrency ***/
}
