// WARNING: to fully use the checkFieldsData(),
//          you MUST INCLUDE the following files before this file in the JSP page. 
//          /pro/javascript/check_functions.js
//          /pro/javascript/*lge*/survey_titles.js


var ST_MONTH= new Array(ST_MONTH_WORD, 
		ST_MONTH_01, 
		ST_MONTH_02,
		ST_MONTH_03,
		ST_MONTH_04,
		ST_MONTH_05,
		ST_MONTH_06,
		ST_MONTH_07,
		ST_MONTH_08,
		ST_MONTH_09,
		ST_MONTH_10,
		ST_MONTH_11,
		ST_MONTH_12);

// ======= Form checking =======
function checkFieldsData()
{
 // TODO !!!!
 return true;
}


// ======= Action on Fields  =======

var CHECKBOX_PARAM_PREFIX = "aachkbxzz";

// ++ Switch on [act==1] or off [act==0], or toggle [act==-1] the checkbox 
//    built with nameValueCheckBoxFactory (WARNING: NOT Collect !!) 
function swCheckBoxFactory( frm, keyName, act )
{
  objCb  = frm.elements[CHECKBOX_PARAM_PREFIX + keyName];  // Only one checkbox (NO collect)
  objHid = frm.elements[keyName];
  if (!objCb || !objHid) return;

  if (act==-1)
    act = (objCb.checked ? 0 : 1);
  if (act==0)
  { objCb.checked = false; objHid.value = ""; }
  else
  { objCb.checked = true;  objHid.value = objHid.bakCheckedValue; }
  return;
}


// ---- DEPRECATED: use confirmEmail instead ----
// Call with true for initialization from body onLoad (or with initial value during page display)
FF_initMel = "";
function doubleCheckEmail(mel, isOblig, isOnLoadInit)
{
 if (isOnLoadInit)
 { FF_initMel = mel; return; }
 if (isEmptyTrimmed(mel))
 {
   if (isOblig)  
   { alert(ST_COMPULSORY_EMAIL); return false; }
   return true;
 }
 if (! isEmail(mel))
 { alert(ST_BAD_EMAIL); return false; }
 if (mel != FF_initMel)
 {
   if (! confirm(ST_EMAIL_CONFIRM +"\n"+ mel))
     return false;
 }
 return true;
}
// -------------------------------------

// Check an email and ask confirm if email is new (replace doubleCheckEmail)
function confirmEmail(frm, elementName, isOblig)
{
 obj = frm.elements[elementName];
 if (!obj)
   return (! isOblig);
 if ("-" == obj.value)
   obj.value = "";
 mel = obj.value;
 if (isEmptyTrimmed(mel))
 {
   if (isOblig)  
   { alert(ST_COMPULSORY_EMAIL); return false; }
   return true;
 }
 if (! isEmail(mel))
 { alert(ST_BAD_EMAIL); return false; }
 if (mel != obj.defaultValue)
 {
   if (! confirm(ST_EMAIL_CONFIRM + mel))
     return false;
 }
 return true;
}


// ======= Fields Display =======
var FF_AMPM_MODE = false;  // Default is 24 hours. Set it to true if AM/PM mode needed
var FF_MONTHDAY_MODE = false;  // displays month before day if yes

function L_Jour(sel)
{ for(i=1; i<=31; i++)
  document.write("<option value='", i,(i==sel)?"' selected>":"'>", i,"</option>"); }
function L_JourBad(sel)
{ document.write('<option value="0">',ST_DAY_WORD,'<\/option>');
  for(i=1; i<=31; i++)
   document.write('<option value="', i,(i==sel)?'" selected>':'">', i,'<\/option>'); }
function L_Mois(sel)
{ for(i=1; i<=12; i++)
  document.write("<option value='", i,(i==sel)?"' selected>":"'>", i,"</option>"); }
function L_MoisTxt(sel)
{ for(i=1; i<=12; i++)
  document.write("<option value='", i,(i==sel)?"' selected>":"'>", ST_MONTH[i],"</option>"); }
function L_MoisBad(sel)
{ document.write('<option value="0">',ST_MONTH_WORD,'<\/option>');
  for(i=1; i<=12; i++)
  document.write("<option value='", i,(i==sel)?"' selected>":"'>", i,"</option>"); }
function L_MoisTxtBad(sel)
{ for(var i=0; i<=12; i++)
  document.write("<option value='", i,(i==sel)?"' selected>":"'>", ST_MONTH[i],"</option>"); }
function L_An(sel, nbBefore,nbAfter)
{ 
  dt = new Date(); dy = dt.getFullYear();
  y1 = dy - 5;   // [y1, y2[
  y2 = dy + 10;
  if (nbBefore && nbBefore > 0) y1 = ( nbBefore > 1000 ? nbBefore : dy - nbBefore) ;
  if (nbAfter  && nbAfter  > 0) y2 = ( nbAfter  > 1000 ? nbAfter  : dy + nbAfter) ;
  //if ( sel < y1 || sel >= y2) sel = dy;  // If no dy, then it'll be current year
  document.write('<option value="0">',ST_YEAR_WORD,'<\/option>');
  for(i=y1; i < y2; i++)
   document.write("<option value='",i,(i==sel ? "' selected>":"'>"), i,"</option>"); 
}
function L_Heure(sel)
{
 if (FF_AMPM_MODE)
 {
  var k = 12;
  for(var i=0; i<=11; i++)
  { document.write('<option value="', i, (i==sel?'" selected>':'">'), (k<10 ?'&nbsp;':''),k,' AM</option>'); 
    k=i+1; }
  for(i=12; i<=23; i++)
  { document.write('<option value="', i, (i==sel?'" selected>':'">'), (k<10 ?'&nbsp;':''),k,' PM</option>'); 
    k=i-11; }
 }
 else
  for(var i=0; i<=23; i++)
   document.write('<option value="', i, (i==sel?'" selected>':'">'), (i<10 ?'0':''),i,'</option>'); 
}
function L_Min(sel)
{ for(var i=0; i<=59; i++)
  document.write('<option value="', i, (i==sel?'" selected>':'">'), (i<10 ?'0':''),i,'</option>'); }



// ----- Date and Time -----
function FF_DateTime(prefx,keyname, yy,mm,dd, hr,mn, extraParams)
{
 FF_DateTxt(prefx,keyname, yy,mm,dd, extraParams);
 document.write('&nbsp;',ST_DAY_AT,'&nbsp;');
 FF_Time(prefx,keyname, hr,mn, extraParams);
 return;
}

// ----- Time -----
function FF_Time(prefx,keyname, hr,mn, extraParams)
{
 document.write('<select name="',prefx,'H',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
 L_Heure(hr);
 document.write('</select>:<select name="',prefx,'N',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
 L_Min(mn);
 document.write('</select>');
 return;
}

function getTimeHour(frm,prefx,keyname)
{
  return _getTime(frm,prefx,"H",keyname);
}
function getTimeMinute(frm,prefx,keyname)
{
  return _getTime(frm,prefx,"N",keyname);
}

/** PRIVE **/
function _getTime(frm,prefx,HorN,keyname)
{
  if (frm==null || frm.elements.length < 1)
    return -1;
  hElm = frm.elements[prefx+HorN+keyname];
  return parseInt( (hElm==null || hElm.options.length < 1) ? -1 : hElm.options[hElm.selectedIndex].value, 10);
}

// --- To customize Year bounds
var FF_YearBoundMin = new Array();  // Indexed by keyname
var FF_YearBoundMax = new Array();

// ----- Date -----
function FF_Date(prefx,keyname, yy,mm,dd, extraParams)
{
 if (FF_MONTHDAY_MODE)
 {
	 document.write('<select name="',prefx,'M',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	 L_MoisBad(mm);
	 document.write('</select><select name="',prefx,'D',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	 L_JourBad(dd);
 }
 else
 {
	 document.write('<select name="',prefx,'D',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	 L_JourBad(dd);
	 document.write('</select><select name="',prefx,'M',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	 L_MoisBad(mm);
 }	 
 document.write('</select><select name="',prefx,'Y',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
 L_An(yy, FF_YearBoundMin[keyname], FF_YearBoundMax[keyname]);
 document.write('</select>');
 return;
}

// ----- Date Month in Text -----
function FF_DateTxt(prefx,keyname, yy,mm,dd, extraParams)
{
 if (FF_MONTHDAY_MODE)
 {
	document.write('<select name="',prefx,'M',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	L_MoisTxtBad(mm);
	document.write('</select><select name="',prefx,'D',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	L_JourBad(dd);
 }
 else
 {
	document.write('<select name="',prefx,'D',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	L_JourBad(dd);
	document.write('</select><select name="',prefx,'M',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
	L_MoisTxtBad(mm);
 }
 document.write('</select><select name="',prefx,'Y',keyname,'" size="1" ',(extraParams?extraParams:''),'>');
 L_An(yy, FF_YearBoundMin[keyname], FF_YearBoundMax[keyname]);
 document.write('</select>');
 return;
}

// ----- Date -----
function FF_CreditCardDate(prefx,keyname, yy,mm,dd)
{
 document.write('<input type="hidden" name="',prefx,'D',keyname,'" value="1" />');
 document.write('<select name="',prefx,'M',keyname,'" size="1">');
 L_Mois(mm);
 document.write('</select><select name="',prefx,'Y',keyname,'" size="1">');
 L_An(yy,1,3);
 document.write('</select>');
 return;
}


// ----- Bad Date -----
function FF_BadDate(prefx,keyname, yy,mm,dd)
{
 document.write('<select name="',prefx,'D',keyname,'" size="1">');
 L_JourBad(dd);
 document.write('</select><select name="',prefx,'M',keyname,'" size="1">');
 L_MoisTxtBad(mm);
 document.write('</select><input type="text" name="',prefx,'Y',keyname,'" value="', 
  (yy<0 ? ST_YEAR_WORD : yy),'" size="6" maxlength="4" />');
 return;
}

// ----- Personal ! -----
function FF_Sex(keyname, F_SEX_MR, F_SEX_MME, F_SEX_MLLE, sex)
{
 document.write(ST_MR,'<input type="radio" name="',keyname,'" value="',F_SEX_MR,'" ',
  (sex==F_SEX_MR ? 'checked' : ''), ' />&nbsp;');
 document.write(ST_MME,'<input type="radio" name="',keyname,'" value="',F_SEX_MME,'" ',
  (sex==F_SEX_MME ? 'checked' : ''), ' />&nbsp;');
 document.write(ST_MLLE,'<input type="radio" name="',keyname,'" value="',F_SEX_MLLE,'" ',
  (sex==F_SEX_MLLE ? 'checked' : ''), ' />&nbsp;');
 return;
}

// ----- Address -----
function FF_Address(fieldname,labeel,strNum,strNam,town,cp,pays,dept,addinfo)
{
 document.write('<input type="hidden" name="',fieldname,'" value="">'); // Field en champ caché
 // document.write('<tr><td colspan="4"><input type="text" size="22" maxlength="50" ', labeel, ' /></td></tr>');
 document.write('<tr><td>Rue</td><td colspan="3" >N&deg;');
 document.write('<input type="text" size="8" maxlength="20" ', strNum); // Numéro de rue
 document.write('/><input type="text" size="40" maxlength="250" ', strNam);
 document.write('></td></tr><tr><td>Ville</td><td>');
 document.write('<input type="text" size="20" maxlength="50" ', town); // Ville
 document.write('/></td><td>Code Postal');
 document.write('</td><td><input type="text" size="10" maxlength="10" ', cp);
 document.write('/></td></tr><tr><td>Pays</td><td>');
 document.write('<input type="text" size="20" maxlength="50" ', pays);  // Pays
 document.write('/></td><td>Département');
 document.write('</td><td><input type="text" size="20" maxlength="50" ', dept);  // Dépt
 document.write('/></td></tr><tr><td>Indications, compléments...</td><td colspan="3" >');
 document.write('<input type="text" size="20" maxlength="250" ', addinfo);
 document.write('/></td></tr>');
 return;
}


// ----- Select ----- 
//  Pour ne rien sélectionner, mettre par exemple en première 
//   ligne dans dispArr "Sélectionner..." avec valeur
//   correspondante "" dans valArr
function FF_SelectDisplay(keyname, val, valArr, dispArr)
{
 document.write('<select name="',keyname,'">');
 for (i=0; i<dispArr.length; i++)
 {
  document.write('<option value="',valArr[i],'" ',
   (val==valArr[i] ? 'selected':''), '>',dispArr[i],'</option>');
 }
 document.write('</select>');
 return;
}

// ----- Select with "AUTRE" input text -----
// ATTENTION, UN SEUL pour un keyname donné !!
function FF_SelectDisplayOther(keyname, val, valArr, dispArr)
{
 selct=false;
 document.write('<select name="',keyname,'" onChange="elm=this.form.SELOTHER',keyname,
 '; if (elm) { if (selectedIndex==(options.length-1)) elm.disabled=false; else elm.disabled=true; }" >');
 for (i=0; i<dispArr.length; i++)
 {
  selct = selct || (val==valArr[i]); 
  document.write('<option value="',valArr[i],'" ',
   (val==valArr[i] ? 'selected':''), '>',dispArr[i],'</option>');
 }
 document.write('<option value="',(selct ? '' : val), '" ', 
  ((selct || val=="") ? '>' : 'selected>'),
  ST_OTHER_WORD,'</option></select>');
 return;
}
  
// -- Complementary part : display the text box for "AUTRE"
function FF_SelectDisplayOtherPart2(keyname, val)
{
 document.write('<input name="SELOTHER',keyname,'" value="',val,
 '" onChange="elm=this.form.',keyname,'; elm.options[elm.options.length-1].value=this.value; elm.selectedIndex=elm.options.length-1; " />');
 return;
}


//photo et thumbnail d'un guest
//deprecated, use FF_addGuestPhoto
function FF_addImg(imgDir, imgFile)
{
  if (imgFile)
  {
    document.imgPhoto.src = imgDir+"tn_"+imgFile;
    frm = document.forms['questForm'];
    frm.ff3t1060c4.value = imgDir+imgFile; 
    frm.ff3t1058c4.value = imgDir+"tn_"+imgFile;
  }
}

//encode guestPhotoImg
function encodeGuestPhotoImg(img)
{
    var TWO_POWER_26_MINUS_ONE = ((1 << 26) - 1);
    nowMillis =  "?_TIM_=eb"+ ( (new Date()).getTime() & TWO_POWER_26_MINUS_ONE ) ;
    return (img + nowMillis);
}

//photo et thumbnail d'un guest
function FF_addGuestPhoto(imgDir, tnImgFile, hdImgFile) {
  FF_addGuestPhoto(imgDir, tnImgFile, hdImgFile, "ff3t1060c4", "ff3t1058c4");
}

function FF_addGuestPhoto(imgDir, tnImgFile, hdImgFile, storePhotoField, storeThumbField) {
  if (tnImgFile) {
    encodedImgUrl = encodeGuestPhotoImg(imgDir+tnImgFile);
    //alert(encodedImgUrl);
    document.imgPhoto.src = encodedImgUrl;
    frm = document.forms['questForm'];
    setGenericValue(frm, storePhotoField, imgDir+hdImgFile);
    // alert(storePhotoField+": "+getGenericValue(frm, storePhotoField));
    setGenericValue(frm, storeThumbField, imgDir+tnImgFile);
    // alert(storeThumbField+": "+getGenericValue(frm, storeThumbField));
  }
}



// ========================= Javascript propre aux REGISTRATIONS ===============================

// --- Liste des EventParts ---
RR_nbRows=0;
RR_evPartIds = new Array();
RR_evPartNames = new Array();

// --- Select Box des EventParts. Si confirmation de changement, modifier la liste des tables
function RR_wrEvpAlert(box,k,currEvpId)
{
 if(! confirm(ST_CONFIRM_EVP_CHANGE)) 
 { box.value=currEvpId; return; }
 selectTable(box.form, box, k);
 return;
}

// ---
function RR_writeEventParts(k,currEvpId)
{
  document.write( '<select name="sreg_EvpId_',k,'" onChange="RR_wrEvpAlert(this,',k,',',currEvpId,')">');
  for(i=0; i<RR_evPartIds.length; i++)
    document.write( '<option value="',RR_evPartIds[i],'" ', (currEvpId==RR_evPartIds[i] ? 'selected>' : '>'),
                    RR_evPartNames[i],'</option>' );
  document.write('</select>');
  return;
}

// --- Select Box des Status
RR_statusValues = new Array(50, 45, 15, 10, 5, 2);   // Ceux que l'on veut afficher 
RR_statusTitles = ST_STATUS_TITLES;

function RR_writeStatus(k, statValues, statTitles, regSt)
{
 document.write( '<select name="sreg_Status_',k,'" ',
   'onChange="if(! confirm(ST_CONFIRM_STATUS_CHANGE)) this.value=regSt;">');
 for (i=0; i<statValues.length; i++)
   document.write( '<option value="', statValues[i],'" ', (regSt==statValues[i] ? 'selected>' : '>'),
	statTitles[statValues[i]],'</option>' );
 document.write('</select>');
}

// --- SelectBox de l'entité invitante
function RR_writeEntities(k, invMemId, memberIds, memberNames)
{
	document.write( '<select name="sreg_MemberId_',k,'" ',
   'onChange="if(! confirm(ST_CONFIRM_MID_CHANGE)) this.value=\'',invMemId,'\';">');
  for (i=0; i<memberIds.length; i++)
   document.write( '<option value="', memberIds[i],'" ', (invMemId==memberIds[i] ? 'selected>' : '>'),
	memberNames[i],'</option>' );
  document.write('</select>');
}

// --- Sélection de la table dans tables['evpid']
function RR_writeTables(k, seatRef, evpId)
{
	s_evpId = ""+evpId;
	document.write('<select name="sreg_SeatRef_',k,'"><option value="">',ST_NONE_WORD,'</option>');
	if (tables[s_evpId])
	{
		for (i=0; i<tables[s_evpId].length; i++)
			document.write( '<option value="', tables[s_evpId][i],'" ', 
		    (seatRef==tables[s_evpId][i] ? 'selected>' : '>'), tables[s_evpId][i],'</option>' );									
	}
}

// --- Modifie la selectBox des tables
function selectTable(frm,optionList,k)
{
  tableList = tables[optionList[optionList.selectedIndex].value];
  tableOptions = frm.elements["sreg_SeatRef_"+k].options;
	oldTable = frm.elements["sreg_SeatRef_"+k].value;
  i=0;
  if ( tableList )
  {
    for (; i<tableList.length; i++)
    {
      tableOptions[i+1]=new Option(tableList[i], tableList[i], false, oldTable==tableList[i]);
    }
  }
  tableOptions.length=(i+1);
}

// TODO : SeatCOUNT et PREF_RANK !!!!!!!!!!!!!!!!!!!!!!!!!!!
// --- Ecrit la ligne entière d'une inscription en lignes Unnumbered List (<ul>)
function RR_InscriptionEvPart(k, statValues, statTitles, 
					   evpId, status, poStatus, role, invMemId, seatRef, regInfo, bookerName)
{
  if (RR_nbRows <= k) RR_nbRows=k+1;
  document.write( '<input type="hidden" name="sreg_MemberId_',k,'" value="',invMemId,'" />',
                  '<input type="hidden" name="sreg_Info_',k,'" value="',regInfo,'" />',
                  '<input type="hidden" name="sreg_Role_',k,'" value="',role,'" />',
                  '<input type="hidden" name="sreg_PostStatus_',k,'" value="',poStatus,'" />',
                  '<li style="margin-bottom:5px;">' );
  RR_writeEventParts(k,evpId);
  document.write( ' &nbsp;&nbsp;',ST_IN_STATUS,'&nbsp;');
  RR_writeStatus(k,statValues,statTitles,status);
  document.write( '<br />',ST_BOOKER_CAPTION,'&nbsp;',
                  '<input type="text" size="20" name="sreg_BookerName_',k,'", value="',bookerName,
			            '" style="margin-top:2px;" />' );
	document.write('&nbsp;&nbsp;',ST_TABLE_CAPTION,'&nbsp;:&nbsp;');
	RR_writeTables(k, seatRef, evpId);
  document.write('</li>' );
}

// --- Ecrit la ligne entière d'une inscription en lignes Unnumbered List (<ul>)
//     pour un administrateur avec possibilité de changer l'entité invitante parmi les valeurs définies dans
//     memberIds et memberNames (tableaux js )

function RR_InscriptionEvPartAdmin(k, statValues, statTitles, 
					   evpId, status, poStatus, role, seatRef, regInfo, bookerName,
						 invMemId, memberIds, memberNames)
{
  if (RR_nbRows <= k) RR_nbRows=k+1;
  document.write( '<input type="hidden" name="sreg_Info_',k,'" value="',regInfo,'" />',
                  '<input type="hidden" name="sreg_Role_',k,'" value="',role,'" />',
                  '<input type="hidden" name="sreg_PostStatus_',k,'" value="',poStatus,'" />',
                  '<li style="margin-bottom:5px;">' );
  RR_writeEventParts(k,evpId);
  document.write( ' &nbsp;&nbsp;',ST_IN_STATUS,'&nbsp;');
  RR_writeStatus(k,statValues,statTitles,status);
	document.write( '<br />',ST_INVITING_BU,'&nbsp;');
	RR_writeEntities(k,invMemId, memberIds, memberNames);
  document.write( '<br />',ST_BOOKER_CAPTION,'&nbsp;',
                  '<input type="text" size="20" name="sreg_BookerName_',k,'", value="',bookerName,
            			'" style="margin-top:2px;" />' );
	document.write('&nbsp;&nbsp;',ST_TABLE_CAPTION,'&nbsp;:&nbsp;');
	RR_writeTables(k, seatRef, evpId);
	document.write('</li>' );
}



// ========================= Javascript propre aux CASCADING SELECTS ===============================
/**
 *  Tous les indices commencent à 0. 
 *  Les idLevelX ne doivent JAMAIS être nuls ou valoir 0.
 *  Il est du ressort de la page HTML/JSP de déclarer les <select>   
 *    et d'appeler SF_selectCascadeInit dans le <body onLoad=" ... "> ou APRES la balise </form> de fin du formulaire (mais là le defaultSelected ne fonctionne pas)
 *  Le js ajoute automatiquement les ON_CHANGE AVANT ceux éventuellement définis sur les select (ajoutés par SF_selectCascadeInit, sauf sur le dernier select)
 *
 *  Utilisation:
 *    1/ Ajouter toutes les Options par des SF_addCascade( groupName, level, parentIds, myId, optionValue, optionText);
 *       NB:  - parentIds ignoré pour level=0
 *            - parentIds peut être un number ou un Array de taille 1 pour level=1  
 *            - parentIds est un Array de longueur level, contenant tous les Ids de niveaux successifs pour arriver au noeud de l'arbre
 *            - groupName ne doit pas contenir de quotes, simples ou doubles !
 *       ATTENTION: TOUJOURS appeler les SF_addCascade dans L'ORDRE DES LEVELS CROISSANTS !!
 *                  Je vous aurai prévenu, ça explose sinon !!
 *
 *    2/ Appeler SF_selectCascadeInit( groupName, levelMax, Array_des_Select_Box_Objects, default_selected_value_of_first_selBox)
 *       NB:  - Array_default peut être null si pas de valeurs sélectionnées par défaut
 *            - Rien n'empêche de mettre des <option> dans la page HTML/JSP, notamment s'il faut mettre "Sélectionner..."
 *              Evidemment, seul le niveau 0 les gardera une fois que l'utilisateur aura commencé à jouer. 
 *            - Si le levelMax est inférieur au LevelMax calculé, gueule !
 *            - Trois attributs sont positionnés sur le select: .persoId (=myId) .persoGrp (=groupName) et .persoIndex (=level) 
 *            - La méthode rajoute les onChange AUTOMATIQUEMENT !
 * 
 *    3/ SF_selectOptionById( groupName, level, idToSelect ) et 
 *       SF_selectOptionByValue( groupName, level, valueToSelect )  permettent de positionner une selectBox donnée 
 *              (celle identifiée par groupName & level) et de cascader sur celles d'après. 
 *
 *  SF_CascadeSelectObjects[GroupName][i] est l'objet Javascript Select de la select box de i-ème niveau
 *  SF_CascadeLevelMax[GroupName] = level max pour ce GroupName. Attention, correspond à l'indice le plus haut et non la taille!!
 *  SF_CascadeTable[GroupName][idLevel0][idLevel1][idLevel2]...[0] = new Array( optionValue, optionText )
 *                                                         (order: as appeared in successive adds)
 */

var SF_CascadeSelectObjects = new Array();
var SF_CascadeLevelMax      = new Array();
var SF_CascadeTable         = new Array();
var SF_CascadeOnChangeFunc  = new Array();

function SF_addCascade( groupName, level, parentIds, myId, optionValue, optionText )
{
  if (! SF_CascadeTable[groupName] )
  {
    SF_CascadeSelectObjects[groupName] = new Array();
    SF_CascadeLevelMax[groupName]      = 0;
    SF_CascadeTable[groupName]         = new Array();
    SF_CascadeOnChangeFunc[groupName]  = new Array();
  }
  if (SF_CascadeLevelMax[groupName] < level)
      SF_CascadeLevelMax[groupName] = level;
      
  // PAS DE CHECK DES ARRAYS car on suppose que l'appel est PAR LEVEL CROISSANTS !!
  parentArray = _SF_getParentCascadeArray( groupName, level, parentIds )
  parentArray[myId] = new Array();
  parentArray[myId][0] = new Array( optionValue, optionText );
  return;
}


function SF_selectCascadeInit( groupName, levelMax, selBoxArray)
{
  if (! SF_CascadeTable[groupName] )
    { alert("Inconsistent groupName in SF_selectCascadeInit!!"); return; }
  if (SF_CascadeLevelMax[groupName] > levelMax)
    { alert("Inconsistent max level in SF_selectCascadeInit!!"); return; }

  // Positionne la première SelectBox
  _SF_setOptionList( selBoxArray[0].options, SF_CascadeTable[groupName], null, true );

  // ----- Construit les selectBoxes onChange
  for (i=0; i < selBoxArray.length; i++)
  {
    SF_CascadeSelectObjects[groupName][i] = selBoxArray[i];
    selBoxArray[i].persoGrp = groupName;     // Custom properties
    selBoxArray[i].persoIndex = i;
	  if (i < selBoxArray.length - 1)
    {
      SF_CascadeOnChangeFunc[groupName][i] = selBoxArray[i].onchange;
      selBoxArray[i].onchange = function(event) 
        { _SF_onChangeHandler(event); if (SF_CascadeOnChangeFunc[groupName][i]) return SF_CascadeOnChangeFunc[groupName][i](event); return; };
    }
  }
  return;
}

/** WARNING: Suppose the optionList IS ALREADY SET !!  Return true on success **/
function SF_selectOptionById( groupName, level, idToSelect )
{
  selBoxArray = SF_CascadeSelectObjects[groupName];
  if ( (! selBoxArray) || level >= selBoxArray.length)  return;
  selBox = selBoxArray[level];
  for (i=0; i < selBox.options.length; i++)
  {
    opt = selBox.options[i];
    if (opt.persoId == idToSelect)
    {
      opt.selected = true;
      selBox.selectedIndex = opt.index;
      _SF_onChange(selBox, false);
      return true;
    }
  }
  return false;
}

/** WARNING: Suppose the optionList IS ALREADY SET !! **/
function SF_selectOptionByValue( groupName, level, valueToSelect )
{
  // alert( "SF_selectOptionByValue("+groupName+", "+level+", "+valueToSelect+" )" );
  selBoxArray = SF_CascadeSelectObjects[groupName];
  if ( (! selBoxArray) || level >= selBoxArray.length)  return;
  selBox = selBoxArray[level];
  for (i=0; i < selBox.options.length; i++)
  {
    opt = selBox.options[i];
    if (opt.value == valueToSelect)
    {
      opt.selected = true;
      selBox.selectedIndex = opt.index;
      _SF_onChange(selBox,false);
      return true;
    }
  }
  return false;
}


/** Get the last value of the select boxes that is not null **/
function SF_getLastNonNullValue( groupName )
{
  var maxLev = SF_CascadeLevelMax[groupName];
  if ( maxLev==null || maxLev < 0)
    return null;
  for (var k = maxLev; k >= 0; k--)
  {
    var sb  = SF_CascadeSelectObjects[groupName][k];
    var val = (sb.selectedIndex < 0 ? null : sb.options[sb.selectedIndex].value);
    if (val && !isEmptyTrimmed(val))
      return val;
  }
  return null;
}




/** PRIVE **/
function _SF_onChangeHandler(event)
{
  winevent = (window.event?window.event:event);
  _SF_onChange(winevent.srcElement?winevent.srcElement:winevent.target,false);
}
/** PRIVE **/
function _SF_onChange( selBox, doNotShow )
{
  grp    = selBox.persoGrp;
  idx    = selBox.persoIndex;
  slbGrp = SF_CascadeSelectObjects[grp];

  // Toggle display for the next one
  if (!doNotShow && slbGrp[idx+1]) 
  { slbGrp[idx+1].style.display = "inline"; slbGrp[idx+1].style.visibility = "visible"; }

  for(var i=idx+1; i <= SF_CascadeLevelMax[grp]; i++)
  {
    if (! slbGrp[i]) { alert("ERREUR ! slbGrp["+i+"] n'existe pas !!!"); break; }
    cascArr = new Array();
    for (m=0; m < i; m++)
    {
      // alert("i="+i+" m="+m);
      if (slbGrp[m].options && slbGrp[m].options.length > 0)
        cascArr[m] = slbGrp[m].options[ slbGrp[m].selectedIndex ].persoId;
    }
    // alert( "i="+i+" cascArr="+cascArr );  
    _SF_setOptionList( slbGrp[i].options, _SF_getParentCascadeArray(grp, i, cascArr), null );
  }
  return;
}


/** PRIVE **/
function _SF_setOptionList( selBoxOptionArray, parentCascadeArray, selectedVal, isAppendMode )
{
  count = (isAppendMode ? selBoxOptionArray.length : 0);
  if (parentCascadeArray)
    for (key in parentCascadeArray)
    {
      if ( key==0 || (! parentCascadeArray[key]) || typeof(parentCascadeArray[key]) != "object" )
        continue;
      isSel = (parentCascadeArray[key][0][0]==selectedVal);  
      selBoxOptionArray[count] = new Option( parentCascadeArray[key][0][1], parentCascadeArray[key][0][0], isSel, isSel );
      selBoxOptionArray[count].persoId = key;
      count++;
    }
  selBoxOptionArray.length = count;
  return;
}

/** PRIVE **/
function _SF_getParentCascadeArray( groupName, level, parentIds )
{
  // PAS DE CHECK DES ARRAYS car on suppose que l'appel est PAR LEVEL CROISSANTS !!
  switch (level)
  {
    case 0:  return SF_CascadeTable[groupName];
    case 1:  parId = ( typeof(parentIds) == "number" ? parentIds : parentIds[0] ); 
             return SF_CascadeTable[groupName][ parId ];
    case 2:  ct = SF_CascadeTable[groupName][ parentIds[0] ];
             return ( ct ? ct[ parentIds[1] ] : null );
    case 3:  ct = SF_CascadeTable[groupName][ parentIds[0] ];
             return ( ct && ct[ parentIds[1] ] ? ct[ parentIds[1] ][ parentIds[2] ] : null );
    case 4:  ct = SF_CascadeTable[groupName][ parentIds[0] ];
             return ( ct && ct[ parentIds[1] ] && ct[ parentIds[1] ][ parentIds[2] ]   
                    ? ct[ parentIds[1] ][ parentIds[2] ][ parentIds[3] ] : null );
    /*case 5:  ct = SF_CascadeTable[groupName][ parentIds[0] ];
             return (	ct && ct[ parentIds[1] ] && ct[ parentIds[1] ][ parentIds[2] ]   
                    ? ct[ parentIds[1] ][ parentIds[2] ][ parentIds[3] ] 
                    	? ct[ parentIds[1] ][ parentIds[2] ][ parentIds[3] ][ parentIds[4] ]
                    	: null
                    : null
             );*/
    default:
      alert("Level greater than 4 not handled in survey_factory !!");
  }
  return null;
}

// ==========================================================================================



/*
  reopens the survey in a popup setting the pg param to the specified value
*/
function popupSurveyPg(pgValue, wid, hei, popupName)
{
  if (!wid)
    wid=500;
  if (!hei)
    hei=500;
  if (!popupName)
    popupName='popup';

  var oldPage= document.reloadForm.pg.value;
  var oldTarget = document.reloadForm.target;
  
  if(popupName == 'popup')
    OpenWindow('/pro/common/voidpage.htm', wid, hei);
  else
    OpenNamedWindow('/pro/common/voidpage.htm', wid, hei, popupName);

  openSurveyPg(pgValue, popupName);
}
/*
  reopens the survey in the specified target
*/
function openSurveyPg(pgValue, targetName)
{
  var oldPage= document.reloadForm.pg.value;
  var oldTarget = document.reloadForm.target;
  document.reloadForm.pg.value=pgValue;
  document.reloadForm.target=targetName;
  document.reloadForm.submit();

  document.reloadForm.pg.value=oldPage;
  document.reloadForm.target=oldTarget;
}


// ============ QUEST RELOAD FORM ==========================

// -------- For backward compatibility on Surveys ------
// ++ [deprecated] Use chgSubmit preferably !
function internChgParam(paramName, paramValue)
{
  var elm = document.reloadForm.elements[paramName];
  if (! elm)
  {
    elm = document.reloadForm.elements["_zz0_"];
    elm.name = paramName;
  }
  elm.value = paramValue;
}

// ++ [deprecated] Use goto() instead
function chgSubmit(paramName, paramValue, addAct)
{
  if (addAct) document.reloadForm.action += addAct;
  internChgParam(paramName, paramValue);
  document.reloadForm.submit();
}
// ----------------------------------------------------

// ++ Treat params 
function treatReloadFormParams(frm, newParams)
{
  var spareZZidx = 0;
  // Params as "param1=v1&param2=v2" -- Spare elements "_zz0_" ... "_zz9_"
  while (newParams && newParams.length > 0)
  {
    var chunk, paramName, paramVal;
    // --- Treat one pair (param,value)
    var pos = newParams.indexOf("&");
    if (pos == 0)
    {
      newParams = ( (newParams.length > 1) ? newParams.substring(1,newParams.length) : "" );
      continue;
    }
    if (pos > 0)
    {
      chunk = newParams.substring(0,pos);
      if (newParams.length > pos+4 && newParams.substring(pos,pos+5) == "&amp;")
        pos += 4;
      newParams = ( (pos+1 < newParams.length) ? newParams.substring(pos+1,newParams.length) : "" );
    }
    else
    {
      chunk = newParams;
      newParams = "";
    }
    // Extract the param and the value
    pos = chunk.indexOf("=");
    if (pos < 0)
    {
      paramName = chunk;
      paramVal  = "";
    }
    else
    {
      if (pos == 0) continue;   // Invalid param
      paramName = chunk.substring(0,pos);
      paramVal  = ( (pos+1 < chunk.length) ? chunk.substring(pos+1,chunk.length) : "" );
    }
    // Now we have the paramName and paramVal: update the form !
    var elm = frm.elements[paramName];
    if (! elm)
    {
      elm = frm.elements["_zz"+spareZZidx+"_"];
      spareZZidx++;
      elm.name = paramName;
    }
    elm.value = paramVal;
  }
  return;
}

