/**
 * API ScBhvBinder : gère l'association d'un Bhv avec les éléments d'une Source.
 *   - bindNodes(pSrcRoot)
 *   
 * Implementation ScBhvBinderPathBlock : association d'unScBhvBlock via un path.
 * @param pPath voir scPaLib pour la syntaxe du path.
 * @param pBlockConstructor function de type constructor du block.
 * @see ScBhvBlock pour les params pBhvOptions, pDefaultParams, pComputeDefaultFct
 */
function ScBhvBinderPathBlock(pPath, pBhvOptions, pDefaultParams, pComputeDefaultFct, pBlockConstructor){
	this.fPa = scPaLib.compilePath(pPath);
	this.fBhvOptions = pBhvOptions || {};
	this.fConstructor = pBlockConstructor || ScBhvBlock;
	if(pDefaultParams) this.fDefaultParams = pDefaultParams;
	if(pComputeDefaultFct) this.fComputeDefaultFct = pComputeDefaultFct;
}
ScBhvBinderPathBlock.prototype.bindNodes = function(pPage, pSrcRoot){
	var vList = scPaLib.findNodes(this.fPa, pSrcRoot);
	if(vList) for(var i=0; i < vList.length; i++) {
		var vNode = vList[i]; 
		if(!vNode.fBhv && !scPaLib.findNode("anc:tr",vNode)) vNode.fBhv = new this.fConstructor(pPage, vNode, this.fBhvOptions, this.fDefaultParams, this.fComputeDefaultFct);
	}
}

/**
 * Implementation ScBhvBinderClassesBlock : association d'unScBhvBlock via une expression régulière sur l'attribut class de la source.
 * @param pRegExpClasses Expression régulière.
 * @param pBlockConstructor function de type constructor du block.
 * @see ScBhvBlock pour les params pBhvOptions, pDefaultParams, pComputeDefaultFct
 */
function ScBhvBinderClassesBlock(pRegExpClasses, pBhvOptions, pDefaultParams, pComputeDefaultFct, pBlockConstructor){
	this.fRegExpCls = pRegExpClasses;
	this.fBhvOptions = pBhvOptions || {};
	this.fConstructor = pBlockConstructor || ScBhvBlock;
	if(pDefaultParams) this.fDefaultParams = pDefaultParams;
	if(pComputeDefaultFct) this.fComputeDefaultFct = pComputeDefaultFct;
}
ScBhvBinderClassesBlock.prototype.bindNodes = function(pPage, pSrcRoot){
	var vCh = pSrcRoot.firstChild;
	while(vCh) {
		if( ! vCh.fBhv && vCh.nodeType == 1 && !scPaLib.findNode("anc:tr",vCh)) {
			var vCls = vCh.className;
			if(vCls && this.fRegExpCls.test(vCls)) vCh.fBhv = new this.fConstructor(pPage, vCh, this.fBhvOptions, this.fDefaultParams, this.fComputeDefaultFct);
		}
		if(vCh.hasChildNodes() && !scPaLib.findNode("anc:tr",vCh)) {
			vCh = vCh.firstChild;
		} else {
			while( ! vCh.nextSibling) {
				vCh = vCh.parentNode;
				if(vCh === pSrcRoot) return;
			}
			vCh = vCh.nextSibling;
		}	
	}
}



/**
 * API ScBhv : Behavior associé à un élément d'une Source.
 *  Initialisation pres
 *   - computeParams(pRootData) : initialise le block. si pRootData==null applique ses comportements par défaut.
 *   		Si return true le contexte appelant se charge d'appeler les Bhv dans les éléments fils.
 *   - buildSteps(pStepsList) : construit le tableau des steps de la page. 
 *   		Si return true le contexte appelant se charge d'appeler les Bhv dans les éléments fils.
 *   - importBlock(pDstDoc, pDstParent) : importe le block dans le document cible. 
 *   		Retourne le noeud créé. Si la copie a été interrompue, affecte pDstDoc.importStopped = true.
 *   		Append à pDstParent si spécifié. (Méthode appelé par les Steps pour se construire).
 *   - editBlock(pDstDoc, pDstParent) : importe les noeuds dans l'environnement d'édition et les ajoute à pDstParent.
 *   
 *   
 *  Interactions inter-Bhv
 *   - cutBefore : 0, pas de cut avant ce block, X : nb de niveaux hiérarchiques coupés.
 *   - hidden : true/false, si true ce block n'est pas publié.
 *   - tempoBefore : NON IMPLEMENE true/false, si true ajoute un Step pour l'affichage de ce block et suivants.
 *   
 *  Edition :
 *   - saveParams(pRootData) : affecte un arbre de données pour enreg des paramètres (en mode édition).
 *   
 * Implémentation ScBhvBlock :
 *  @param pBhvOptions Options de comportement du Bhv
 *  	- isRootPage : si true, associe à la propriété hidden, la suppression complète de la page (ie y compris dans le plan).
 *      - publishIfNotEmpty : si true, vérifie que son contenu soit non vide (ie texte ou image/object) pour être publié (ie importé dans la view).
 *      - uiEditHidden : si true supprime toute l'interface d'édition de ce block.
 *      - uiEditNoCutBefore : si true supprime le bouton de "cut before" du block
 *      - uiEditNoHidden : si true supprime le bouton de "hidden" du block
 *      - uiEditNoTempoBefore : si true supprime le bouton de "tempoBefore" du block
 *      
 *  @param pComputeDefaultFct  La méthode computeDefaults(pParams) peut-etre définie pour calculer dynamiqument les règles d'affichage par défaut.
 *  @param pDefaultParams Les paramètres d'init peuvent être définis sur pDefaultParams : 
 *  	- cutBefore, tempoBefore, hidden
 */
function ScBhvBlock(pPage, pNode, pBhvOptions, pDefaultParams, pComputeDefaultFct){
	//this.fPage = pPage; Pas mémorisé pour éviter le cycle de ref d'objets => memory leaks.
	this.fNode = pNode;
	this.cutBefore = 0;
	this.tempoBefore = false;
	this.hidden = false;
	this.fOptions = pBhvOptions || {};
	if(pComputeDefaultFct) this.computeDefaults = pComputeDefaultFct;
	if(pDefaultParams) this.fDefaultParams = pDefaultParams;
}
ScBhvBlock.prototype.computeParams = function(pPage, pRootData) {
	if("computeDefaults" in this) {
		//On clone les paramètres par défaut (car peuvent être mutualisés par plusieurs blocks) 
		var vDefParams = {};
		if(this.fDefaultParams) {
			if(scCoLib.isIE) this.copyParams(this.fDefaultParams, vDefParams);
			else vDefParams.__proto__ = this.fDefaultParams;
		} else this.fDefaultParams = {};
		this.fDefaultParams = vDefParams;
		this.computeDefaults(this.fDefaultParams);
	}
	if(this.fDefaultParams) this.copyParams(this.fDefaultParams, this);
	if(pRootData) {
		//On prend en compte les paramètres enregistrés.
		var vData = pRootData[this.getId()];
		if(vData) this.copyParams(vData, this);
	}
	if(this.fOptions.isRootPage) scPresMgr.setHiddenPg(pPage, this.hidden);
	return true;
}
ScBhvBlock.prototype.copyParams = function(pFrom, pTo) {
	if("cutBefore" in pFrom) pTo.cutBefore = pFrom.cutBefore;
	if("tempoBefore" in pFrom) pTo.tempoBefore = pFrom.tempoBefore;
	if("hidden" in pFrom) pTo.hidden = pFrom.hidden;
}
ScBhvBlock.prototype.buildSteps = function(pStepsList) {
	if(this.hidden) return false;
	if(this.cutBefore > 0 || ! pStepsList[1]) {
		//On cut ou on est le 1er block
		 pStepsList[pStepsList.length] = new ScPresStepNewView(this);
	} else if(this.tempoBefore) {
		pStepsList[pStepsList.length] = new ScPresStepAppendBlocks(this);
	}
	return true;
}
ScBhvBlock.prototype.importBlock = function(pDstDoc, pDstParent) {
	var vEltSrc = this.fNode;
	var vEltDst = scPresUt.importElt(vEltSrc, pDstDoc);
	for(var vCh = vEltSrc.firstChild; vCh; vCh = vCh.nextSibling) {
		if("fBhv" in vCh) {
			var vBhv = vCh.fBhv;
			if(vBhv.cutBefore>0 || vBhv.tempoBefore){
				pDstDoc.importStopped = true;
				break;
			}
			if(vBhv.hidden) continue;
			vBhv.importBlock(pDstDoc, vEltDst);
			if(pDstDoc.importStopped) break;
		} else {
			scPresUt.importDeepNodeBhv(vCh, pDstDoc, vEltDst);
		}
	}
	if( ! this.fOptions.publishIfNotEmpty || scPresUt.isFilled(vEltDst)) {
		if(pDstParent) pDstParent.appendChild(vEltDst);
		return vEltDst;
	} else {
		return null;
	}
}
ScBhvBlock.prototype.editBlock = function(pDstDoc, pDstParent) {
	var vEltSrc = this.fNode;
	if(this.fOptions.uiEditHidden) {
		var vEltDst = scPresUt.importElt(vEltSrc, pDstDoc, pDstParent);
		for(var vCh = vEltSrc.firstChild; vCh; vCh = vCh.nextSibling) scPresUt.importDeepNodeEdit(vCh, pDstDoc, vEltDst);
	} else {
		var vRootDst = pDstDoc.createElement("div");
		vRootDst.className = "scPresEditBlock";
		vRootDst.fEditBhv = new ScEditBhvBlock(this, vRootDst);
		var vEltDst = scPresUt.importElt(vEltSrc, pDstDoc, vRootDst);
		for(var vCh = vEltSrc.firstChild; vCh; vCh = vCh.nextSibling) scPresUt.importDeepNodeEdit(vCh, pDstDoc, vEltDst);
		if(pDstParent) pDstParent.appendChild(vRootDst);
		vRootDst.fEditBhv.redraw();
		return vRootDst;
	}
}

ScBhvBlock.prototype.saveParams = function(pRootData) {
	var vDataBlock = null;
	vDataBlock = this.setParamIfOver(vDataBlock, "cutBefore", 0);
	vDataBlock = this.setParamIfOver(vDataBlock, "tempoBefore", false);
	vDataBlock = this.setParamIfOver(vDataBlock, "hidden", false);
	if(vDataBlock) pRootData[this.getId()] = vDataBlock;
}
ScBhvBlock.prototype.setParamIfOver = function(pDataBlock, pKeyParam, pDefaultValue){
	if(! (pKeyParam in this.fDefaultParams)) {
		if(this[pKeyParam] != pDefaultValue) {
			if(! pDataBlock) pDataBlock = {};
			pDataBlock[pKeyParam] = this[pKeyParam];
		}
	} else {
		if(this[pKeyParam] != this.fDefaultParams[pKeyParam]) {
			if(! pDataBlock) pDataBlock = {};
			pDataBlock[pKeyParam] = this[pKeyParam];
		}
	}
	return pDataBlock;
}

ScBhvBlock.prototype.getId = function() {
	if(! this.fId) this.fId = scPresUt.getRelativePath(this.fNode.ownerDocument.body, this.fNode);
	return this.fId;
}


/**
 * Bhv d'édition pour les blocks.
 */
function ScEditBhvBlock(pBhvBlock, pEditBlock){
	this.fBhv = pBhvBlock;
	this.oEditNode = pEditBlock;
	
	var vOptions = this.fBhv.fOptions;
	
 	if( ! vOptions.uiEditNoHidden) {
		this.oHiddenBtn = this.oEditNode.ownerDocument.createElement("a");
		this.oHiddenBtn.href = "#";
		this.oHiddenBtn.onclick = this.onToggleHidden;
		this.oHiddenBtn.className = "scPresHiddenBtn";
		this.oHiddenBtn.title="Masque le bloc";
		this.oEditNode.appendChild(this.oHiddenBtn);
 	}
	
	if( ! vOptions.isRootPage && ! vOptions.uiEditNoCutBefore) {
		this.oCutBtn = this.oEditNode.ownerDocument.createElement("a");
		this.oCutBtn.href = "#";
		this.oCutBtn.onclick = this.onToggleCut;
		this.oCutBtn.className = "scPresCutBeforeBtn";
		this.oCutBtn.title="Ins\u00E8re un saut de page";
		this.oEditNode.appendChild(this.oCutBtn);
	}
	
	this.oBlockOver = this.oEditNode.ownerDocument.createElement("div");
	this.oBlockOver.className = "scPresEditBlockOver";
	this.oEditNode.appendChild(this.oBlockOver);
}
ScEditBhvBlock.prototype.getCutBefore = function() {
	return this.fBhv.cutBefore;
}
ScEditBhvBlock.prototype.getHidden = function() {
	return this.fBhv.hidden;
}
ScEditBhvBlock.prototype.getTempoBefore = function() {
	return this.fBhv.tempoBefore;
}
ScEditBhvBlock.prototype.setCutBefore = function(pValue) {
	scPresMgr.setEditedPageDirty(true);
	this.fBhv.cutBefore = Math.max(pValue, 0);
	if(pValue>0) {
		this.setHidden(false);
		this.setTempoBefore(false);
	}
}
ScEditBhvBlock.prototype.setHidden = function(pHidden) {
	scPresMgr.setEditedPageDirty(true);
	this.fBhv.hidden = pHidden;
	if(pHidden) {
		this.setCutBefore(0);
		this.setTempoBefore(false);
	}
	if(this.fBhv.fOptions.isRootPage) {
		scPresMgr.setHiddenPg(scPresMgr.getCurrPg(), pHidden);
	}
}
ScEditBhvBlock.prototype.setTempoBefore = function(pTempo) {
	scPresMgr.setEditedPageDirty(true);
	this.fBhv.tempoBefore = pTempo;
	if(pTempo) {
		this.setCutBefore(0);
		this.setHidden(false);
	}
}
ScEditBhvBlock.prototype.redraw = function() {
	if(this.getCutBefore()>0) {
		if(this.oEditNode.className.indexOf("scPresCuttedBlock")<0) this.oEditNode.className += " scPresCuttedBlock";
		if( ! this.oCutLine) {
			this.oCutLine = this.oEditNode.ownerDocument.createElement("div");
			this.oCutLine.className = "scPresCutBeforeLine";
			this.oEditNode.insertBefore(this.oCutLine, this.oEditNode.firstChild);
		}
	} else {
		var vClass = this.oEditNode.className;
		var vIdx;
		if( (vIdx = vClass.indexOf("scPresCuttedBlock")) >= 0) this.oEditNode.className = vClass.substring(0, vIdx);
		if(this.oCutLine) {
			this.oEditNode.removeChild(this.oCutLine);
			this.oCutLine = null;
		}
	}
	if(this.getHidden()) {
		if(this.oEditNode.className.indexOf("scPresHiddenBlock")<0) this.oEditNode.className += " scPresHiddenBlock";
	} else {
		var vClass = this.oEditNode.className;
		var vIdx;
		if( (vIdx = vClass.indexOf("scPresHiddenBlock")) >= 0) this.oEditNode.className = vClass.substring(0, vIdx);
	}
}
ScEditBhvBlock.prototype.onToggleHidden = function(pEvent) {
	var vEditBhv = this.parentNode.fEditBhv;
	vEditBhv.setHidden( ! vEditBhv.getHidden());
	vEditBhv.redraw();
	return false;
}
ScEditBhvBlock.prototype.onToggleCut = function(pEvent) {
	var vEditBhv = this.parentNode.fEditBhv;
	vEditBhv.setCutBefore( vEditBhv.getCutBefore()==0 ? 1 : 0);
	vEditBhv.redraw();
	return false;
}



/**
 * API Step : permet de construire une étape.
 *  - show(pStepList, pThisStepIdx, pCurrentStep) : construit et affiche l'étape en fonction de l'étape précédente et du contexte d'enchainement.
 *  - buildNewView(pView) : (méthode optionnelle) reconstruit intégralement la view correspondant à cette étape.
 *  
 * Projet non implémenté pour la gestion des tempo...
 *  - resetView() : View purgée, reset l'état de cette Step.
 *  - appendStep(pView, pParentDst) : (méthode optionnelle) ajoute le contenu de l'étape.
 *  - removeStep() : (méthode optionnelle) supprime le contenu de cette étape
 * ScPresStepNewView : force une nouvelle View. 
 */
function ScPresStepNewView(pBhv){
	this.fStepBhv = pBhv;
}
ScPresStepNewView.prototype.show = function(pStepList, pThisStepIdx, pCurrentStep){
	var vView = scPresMgr.getFreeView();
	this.buildNewView(vView);
	scPresMgr.setCurrentView(vView);
}
ScPresStepNewView.prototype.buildNewView = function(pView){
	var vEltSrc = this.fStepBhv.fNode;
	var vDocDst = pView.ownerDocument;
	vDocDst.importStopped = false;
	var vEltDst = this.fStepBhv.importBlock(vDocDst);
	var vIsStopped = vDocDst.importStopped;
	vDocDst.importStopped = false;
	scPresUt.importAncestorsBhv(vEltSrc, vEltDst, pView);
	if( ! vIsStopped) scPresUt.importNextsBhv(vEltSrc, vDocDst, vEltDst.parentNode, pView);
}

/**
 * ScPresStepAppendBlocks : ajoute du contenu à la View courante (en mode avance normale). 
 */
function ScPresStepAppendBlocks(pBhv){
	this.fStepBhv = pBhv;
}
ScPresStepAppendBlocks.prototype.show = function(){
	//TODO
}



/**** ############## Déclinaison de blocks ############### ***/

 /* Implémentation ScBhvBlockEmbed (block qui contient une balise <object ou <embed à resizer dynamiqement) :
 *  @param pBhvOptions Options de comportement du Bhv
 *  	- voir toutes les options de ScBhvBlock.
 *      - ratioWidth : ratio max  de la largeur du container du contenu (défaut : 80%)
 *      - ratioHeight : ratio max  de la hauteur du container du contenu (défaut : 60%)
 *      - ratioHeightAlone : ratio max  de la hauteur du container du contenu si cette ressource est seule dans la page (défaut : 90%)
 *      - captionHeight : hauteur fixe en pixel à soustraire (loupe, titre...) (défaut : 30px)
 *      
 *  @param pComputeDefaultFct  La méthode computeDefaults(pParams) peut-etre définie pour calculer dynamiqument les règles d'affichage par défaut.
 *  @param pDefaultParams Les paramètres d'init peuvent être définis sur pDefaultParams : 
 *  	- cutBefore, tempoBefore, hidden
 */
function ScBhvBlockEmbed(pPage, pNode, pBhvOptions, pDefaultParams, pComputeDefaultFct){
	ScBhvBlock.call(this, pPage, pNode, pBhvOptions, pDefaultParams, pComputeDefaultFct);
}
ScBhvBlockEmbed.prototype = new  ScBhvBlock();
ScBhvBlockEmbed.prototype.constructor = ScBhvBlockEmbed;

ScBhvBlockEmbed.prototype.fPathResFra = scPaLib.compilePath("chi:div.resFra");
ScBhvBlockEmbed.prototype.fPathObject = scPaLib.compilePath((scCoLib.isIE) ? "des:object" : "des:embed");
ScBhvBlockEmbed.prototype.fPathZoom = scPaLib.compilePath("des:.zoom");

ScBhvBlockEmbed.prototype.xImportBlock = ScBhvBlock.prototype.importBlock;
ScBhvBlockEmbed.prototype.importBlock = function(pDstDoc, pDstParent) {
	var vDst = this.xImportBlock(pDstDoc, pDstParent);
	if(vDst) {
		vDst.fEmbed = scPaLib.findNode(this.fPathObject, vDst);
		vDst.fResFra = scPaLib.findNode(this.fPathResFra, vDst);
		scSiLib.addRule(vDst, this);
		vDst.fZoom = scPaLib.findNode(this.fPathZoom, vDst);
		if(vDst.fZoom) vDst.fZoom.onclick = this.onClickZoom;
	}
	return vDst;
}

ScBhvBlockEmbed.prototype.onResizedAnc = function(pOwnerNode, pEvent) {
	if(pEvent.phase==1) {
		var vObj = pOwnerNode.fEmbed;
		if(!vObj) return;
		if(!vObj.oriW) vObj.oriW = vObj.width || 500;
		if(!vObj.oriH) vObj.oriH = vObj.height || 400;
		
		var vIsAlone = ! this.isEltNotAlone(scPresMgr.getCurrView(), pOwnerNode);	
		
		var vRate = scPresSizeMgr.getRatioNormalScreen();
		var vWantedW = vObj.oriW * vRate;
		var vWantedH = vObj.oriH * vRate;
		var vMaxW = scPresSizeMgr.getMainContentWidth() * (this.fOptions.ratioWidth || .8);
		var vMaxH = scPresSizeMgr.getMainContentHeight() * ( vIsAlone ? (this.fOptions.ratioHeightAlone || .9) : (this.fOptions.ratioHeight || .6) ) - (this.fOptions.captionHeight || 30);
		if(vWantedW > vMaxW || vWantedH > vMaxH) {
			var vRW = vWantedW / vMaxW;
			var vRH = vWantedH / vMaxH;
			if(vRW > vRH) {
				vObj.width = vMaxW;
				vObj.height = vWantedH / vRW;
			} else {
				vObj.width = vWantedW / vRH;
				vObj.height = vMaxH;
			}
			if(pOwnerNode.fZoom) pOwnerNode.fZoom.style.display = "";
		} else {
			vObj.width = vWantedW;
			vObj.height = vWantedH;
			if(pOwnerNode.fZoom) pOwnerNode.fZoom.style.display = "none";
		}
		pOwnerNode.fResFra.style.width=vObj.width+"px";
		pOwnerNode.fResFra.style.height=vObj.height+"px";
	}
}
ScBhvBlockEmbed.prototype.onResizedDes = function(pOwnerNode, pEvent) {}
ScBhvBlockEmbed.prototype.onClickZoom = function(pEvent) {
	var vBhvNode = this;
	while( ! vBhvNode.fEmbed) vBhvNode = vBhvNode.parentNode;
	var vObj = vBhvNode.fEmbed;
	scPresMgr.displayZoom(true);
	var vCt = scPresMgr.getZoomContainer();
	var vDst = scPresUt.importDeepNode(vBhvNode.fEmbed, vCt.ownerDocument, vCt);
	var vResizer = {
		onResizedDes : function(pOwnerNode, pEvent) {},
		onResizedAnc : function(pOwnerNode, pEvent) {
			if(pEvent && pEvent.phase==2) return;
			var vRate = scPresSizeMgr.getRatioNormalScreen() * 1.25; //On force un 25% de plus pour le zoom.
			var vWantedW = vObj.oriW * vRate;
			var vWantedH = vObj.oriH * vRate;
			var vMaxW = vCt.offsetWidth;
			var vMaxH = vCt.offsetHeight;
			if(vWantedW > vMaxW || vWantedH > vMaxH) {
				var vRW = vWantedW / vMaxW;
				var vRH = vWantedH / vMaxH;
				if(vRW > vRH) {
					vDst.width = vMaxW;
					vDst.height = vWantedH / vRW;
				} else {
					vDst.width = vWantedW / vRH;
					vDst.height = vMaxH;
				}
			} else {
				vDst.width = vWantedW;
				vDst.height = vWantedH;
			}
			vDst.style.marginTop = Math.max(0, (vMaxH - vDst.height) / 2)+"px";
		}
	}
	scSiLib.addRule(vDst, vResizer);
	vResizer.onResizedAnc(vDst);
	return false;
}
ScBhvBlockEmbed.prototype.isEltNotAlone = function(pRoot, pEltAlone){
	if(pEltAlone == pRoot) return false;
	switch(pRoot.nodeType) {
		case 1 : 
			var vNm = pRoot.nodeName;
			if(vNm == "IMG" || vNm == "OBJECT" || vNm == "EMBED") return true;
			for(var vCh = pRoot.firstChild; vCh; vCh = vCh.nextSibling) if(this.isEltNotAlone(vCh, pEltAlone)) return true;
			break;
		case 3 :
			return (/\S/.test(pRoot.nodeValue));
	}
	return false;
}



 /* Implémentation ScBhvBlockImg (block qui contient une balise img à resizer dynamiqement) :
 *  @param pBhvOptions Options de comportement du Bhv
 *  	- voir toutes les options de ScBhvBlock.
 *      - ratioWidth : ratio max  de la largeur du container du contenu (défaut : 80%)
 *      - ratioHeight : ratio max  de la hauteur du container du contenu (défaut : 60%)
 *      - ratioHeightAlone : ratio max  de la hauteur du container du contenu si cette ressource est seule dans la page (défaut : 90%)
 *      - captionHeight : hauteur fixe en pixel à soustraire (loupe, titre...) (défaut : 30px)
 *      
 *  @param pComputeDefaultFct  La méthode computeDefaults(pParams) peut-etre définie pour calculer dynamiqument les règles d'affichage par défaut.
 *  @param pDefaultParams Les paramètres d'init peuvent être définis sur pDefaultParams : 
 *  	- cutBefore, tempoBefore, hidden
 */
function ScBhvBlockImg(pPage, pNode, pBhvOptions, pDefaultParams, pComputeDefaultFct){
	ScBhvBlock.call(this, pPage, pNode, pBhvOptions, pDefaultParams, pComputeDefaultFct);
}
ScBhvBlockImg.prototype = new  ScBhvBlockEmbed();
ScBhvBlockImg.prototype.constructor = ScBhvBlockImg;

ScBhvBlockImg.prototype.fPathResFra = scPaLib.compilePath("chi:div.resFra");
ScBhvBlockImg.prototype.fPathImg = scPaLib.compilePath("chi:div.resFra/chi:img");
ScBhvBlockImg.prototype.fPathListImg = scPaLib.compilePath("chi:.imgOthers/chi:img");

ScBhvBlockImg.prototype.importBlock = function(pDstDoc, pDstParent) {
	var vDst = this.xImportBlock(pDstDoc, pDstParent);
	if(vDst) {
		var vImg = scPaLib.findNode(this.fPathImg, vDst);
		if(!vImg) return;
		vDst.fImg = vImg;
		vDst.fResFra = scPaLib.findNode(this.fPathResFra, vDst);
		vDst.fOriW = vImg.width || 500;
		vDst.fOriH = vImg.height || 400;
		vDst.fListImg = scPaLib.findNodes(this.fPathListImg, vDst);
		vDst.fListImg.push({src:vImg.src, width:vImg.width, height:vImg.height});
		scSiLib.addRule(vDst, this);
		vDst.fZoom = scPaLib.findNode(this.fPathZoom, vDst);
		if(vDst.fZoom) vDst.fZoom.onclick = this.onClickZoom;
	}
	return vDst;
}

ScBhvBlockImg.prototype.onResizedAnc = function(pOwnerNode, pEvent) {
	if(pEvent.phase==1) {
		var vImg = pOwnerNode.fImg;
		if(!vImg) return;
		
		var vIsAlone = ! this.isEltNotAlone(scPresMgr.getCurrView(), pOwnerNode);	
		
		var vRate = scPresSizeMgr.getRatioNormalScreen();
		var vWantedW = pOwnerNode.fOriW * vRate;
		var vWantedH = pOwnerNode.fOriH * vRate;
		var vMaxW = scPresSizeMgr.getMainContentWidth() * (this.fOptions.ratioWidth || .8);
		var vMaxH = scPresSizeMgr.getMainContentHeight() * ( vIsAlone ? (this.fOptions.ratioHeightAlone || .9) : (this.fOptions.ratioHeight || .6) ) - (this.fOptions.captionHeight || 30);
		var vFinalW;
		var vZoomOn = false;
		if(vWantedW > vMaxW || vWantedH > vMaxH) {
			var vRH = vWantedH / vMaxH;
			vFinalW = (vWantedW / vMaxW > vRH) ? vMaxW : vWantedW / vRH;
			vZoomOn = true;
		} else {
			vFinalW = vWantedW;
		}
		var vList = pOwnerNode.fListImg;
		for (var i = 1, l = vList.length; i < l; i++) if(vList[i].width > vFinalW) break;
		var vImgSel = vList[i-1];
		vImg.src = vImgSel.src;
		vImg.width = vImgSel.width;
		vImg.height = vImgSel.height;
		pOwnerNode.fResFra.style.width=vImgSel.width+"px";
		pOwnerNode.fResFra.style.height=vImgSel.height+"px";
		pOwnerNode.fZoom.style.display = (vZoomOn && i < l) ? "" : "none";
	}
}

ScBhvBlockImg.prototype.onClickZoom = function(pEvent) {
	var vBhvNode = this;
	while( ! vBhvNode.fImg) vBhvNode = vBhvNode.parentNode;
	var vImg = vBhvNode.fImg;
	scPresMgr.displayZoom(true);
	var vCt = scPresMgr.getZoomContainer();
	var vDst = scPresUt.importNode(vBhvNode.fImg, vCt.ownerDocument, vCt);
	var vResizer = {
		onResizedDes : function(pOwnerNode, pEvent) {},
		onResizedAnc : function(pOwnerNode, pEvent) {
			if(pEvent && pEvent.phase==2) return;
			var vRate = scPresSizeMgr.getRatioNormalScreen() * 1.25; //On force un 25% de plus pour le zoom.
			var vWantedW = vBhvNode.fOriW * vRate;
			var vWantedH = vBhvNode.fOriH * vRate;
			var vMaxW = vCt.offsetWidth;
			var vMaxH = vCt.offsetHeight;
			var vFinalW;
			if(vWantedW > vMaxW || vWantedH > vMaxH) {
				var vRH = vWantedH / vMaxH;
				vFinalW = (vWantedW / vMaxW > vRH) ? vMaxW : vWantedW / vRH;
			} else {
				vFinalW = vWantedW;
			}
			var vList = vBhvNode.fListImg;
			for (var i = 1, l = vList.length; i < l; i++) if(vList[i].width > vFinalW) break;
			var vImgSel = vList[i-1];
			vDst.src = vImgSel.src;
			vDst.width = vImgSel.width;
			vDst.height = vImgSel.height;
			vDst.style.marginTop = Math.max(0, (vMaxH - vDst.height) / 2)+"px";
		}
	}
	scSiLib.addRule(vDst, vResizer);
	vResizer.onResizedAnc(vDst);
	return false;
}
