/********* FlexObject class to be used for embedding of (fullscreen) flash content **********/
/* @param	contentSwf:String	path to content swf										*
/* @param	transitionSwf	path to content swf										*
 * @param 	divID:String		id of flash object (leave empty for fullscreen flash)	*
 * @param 	linkID:String		id for "a"-element to add link for fs-showElem function	*
 * @param 	transparency:Boolean		set true for transparent content swf!			*
 * @param 	jumpTo:String		needed for flash to be able to switch content			*
 * @param 	autoPlay:Boolean	start flash instantly?									*
 * @param wmode:Boolean (optional) 	*/
var FlexEmbed = new Class({
		
	initialize: function(swfFile,swfContainer,objID,transparency,autoPlay,varsObj,bgColor){
		if(!swfobject.hasFlashPlayerVersion("10")){
			PAC.notify("In order to view this document, you have to install the newest flash player.","error");
			return false;
		}
		getBrowserVersion();
		this.flashObj = {};		// the params of this object could be dynamically filled... 
		this.params = {};		// the following params need not to be changed dynamically 
		this.attributes = {};	// optional attributes
		this.status = {};
		this.swfContainer=$(swfContainer);
		this.bgColor=bgColor?bgColor:"#ffffff";
		this.flashObj.width="100%";					// flash object's width
		this.flashObj.height="100%";				// flash object's height
		this.flashObj.version="10";					// flash object's version
		/* the parameters for the flash object */
		this.params.menu="false";					// usually we do not want the user to see the menu
		this.params.allowScriptAccess="sameDomain";		// needed to call ExternalInterface method?
		this.params.allowFullScreen=true;			// maybe fscommand possible from flash after fade in?!
		this.flObjID=objID;
		this.flashvars=varsObj?varsObj:{};
		this.docID=varsObj.docID;
		this.versionID=varsObj.versionID;
		this.flashvars.bgColor=this.bgcolor;				// set default background color
		//this.flashvars.pageLang=getNavigatorLang();
		this.flashObj.id=objID;				// flashobject's ID
		this.params.id=objID;					// flashobject's ID
		this.params.wmode=transparency?"transparent":(window.ie||window.webkit||isFF2?"opaque":"window");		// set wmode based on transparency param!	
		this.params.name=objID;				// flashobject's name
		this.attributes.id=objID;
		this.attributes.name=objID;
		this.defaultPath=this.flashObj.path;  
		if(objID&&this.swfContainer){
			if(this.swfContainer){
			//	this.swfContainer.setStyle("overflow","visible");
				var objContainer=$(objID);
				if(objContainer){
					this.doEmbed(swfFile,objID);
				}else{
					//alert("object "+swfName+" not found!");
				}
			}else{
				//alert("object "+this.swfContainer+" not specified!");
			}
		}else{
			//alert("please specify both object container and its size-relevant parent!");
		}
		this.swfCnt=(!isIE&&!isChrome)?this.swfObj:this.swfContainer;
	},

	/* Do the embedding! */
	doEmbed: function(swfFile,objID){
		this.oldPreview=swfFile.indexOf("Old")>-1;
		this.flashObj.path=swfFile;			// the path of the swf to be embedded
		if(!PAC){		// Txtr-specific
			PAC=new Object();
		}
		try{
			swfobject.embedSWF(swfFile, objID, this.flashObj.width, this.flashObj.height, this.flashObj.version, false, this.flashvars,this.params,this.attributes);
			this.swfObj=swfobject.getObjectById(this.flObjID);
			return true;
		}catch(exc){
			return false;
		}
	},
	
	initFABridge: function(bridgeName){
		try{
			PAC.flexPreview = FABridge[bridgeName].root();
		}catch(e){
			alert("could not init flash/javascript bridge");
		}
	}, 
	
	onUnload: function(){
	},
	
	onBlur: function(event){
		this.swfObj.focus();	// this = swfObj
	},
	
	onMouseOver: function(event){
		try{
			//this.swfObj.focus();	// this = swfObj
			if(PAC.flexPreview&&this.oldPreview){
				if(PAC.flexPreview.onMouseOver)PAC.flexPreview.onMouseOver();
			}
			window.addEvent("mouseup",this.onMouseUpOutside.bind(this));
		}catch(e){
			debug.log(e.message);
		}
	},
	
	onMouseUpOutside: function(event){
		if(event.target!=this.swfObj){
			if(PAC.flexPreview&&this.oldPreview){
				if(PAC.flexPreview.onMouseOut)PAC.flexPreview.onMouseOut();
				if(PAC.flexPreview.setFocus)PAC.flexPreview.setFocus();
			}
			this.swfObj.blur();	// this = swfObj
		}
		window.removeEvent("mouseup",this.onMouseUpOutside.bind(this));
	},
	
	onMouseDown: function(event){
		if(PAC.flexPreview&&this.oldPreview){
			if(PAC.flexPreview.onMouseDown)PAC.flexPreview.onMouseDown();
		}
		if(!isIE)this.swfObj.focus();
	},
	
	onMouseWheel: function(event){
		if(PAC.flexPreview&&this.oldPreview){
			if (!event) var event = window.event;
		    var delta = 0;
		    if (event.wheelDelta) {
		        delta = event.wheelDelta/120;
		        if (window.opera) delta = -delta;
		    } else if (event.detail) {
		        delta = -event.detail/3;
		    }
		    if ( delta != 0 )    this.handleDocMouseWheel(delta);
			
			cancelDOMEvent(event);
		}
	},
	
	onWindowResize: function(){
		this.resizeContent();
	},

	/* show fullscreen flash content	*/
	setFullScreen: function(){
		if(PAC.flexPreview&&this.oldPreview){
			if(PAC.flexPreview.cbFullScreen)PAC.flexPreview.cbFullScreen(true);
		}
		if(isIE){
			document.documentElement.style.overflow="hidden";
		}
		this.hideElements();
		this.fullScreen=true;	
		this.resizeContent();
	},
	
	closeFullScreen: function(){ 
		if(PAC.flexPreview&&this.oldPreview){
			if(PAC.flexPreview.cbFullScreen)PAC.flexPreview.cbFullScreen(false);
		}
		if(isIE){
			document.documentElement.style.overflow="auto";
		}
		this.showElements();
		this.fullScreen=false;	
		this.resizeContent();
	},
	
	resizeContent: function(){
		if(this.swfCnt){
			var coordinates=new Object();
			if(!this.fullScreen){
				if(this.swfContainer.hasClass("flashNoMargin")){
					this.swfContainer.removeClass("flashNoMargin");
				}
			}else{
				this.swfContainer.addClass("flashNoMargin");
			}
			coordinates=this.swfCnt.getCoordinates();
			if(isSafari){
				coordinates.height+=5
			}else{
				coordinates.height+=3;
			}
			if(isChrome){
				this.swfObj.height=coordinates.height-5;
			}
		}
		if(PAC.flexPreview&&this.oldPreview){
			//hack, don't know but it throughs errors...
			if($type(PAC.flexPreview.setSize) == "function") PAC.flexPreview.setSize(coordinates.width,coordinates.height);
		}
	},

	hideElements: function(){
		!this.ancestorSiblings?this.getVisibleElements():false;
		for(var i=0;i<this.ancestors.length;i++){
			var ac=this.ancestors[i];
			ac.addClass("flashNoMargin");
		}
		for(var j=0;j<this.ancestorSiblings.length;j++){
			var acSib=this.ancestorSiblings[j];
			if(acSib.hasClass("invisible")){
				acSib.addClass("flashNoMargin");
			}else{
				acSib.addClass("invisible");
			}
		}
	},
	
	showElements: function(){
		for(var i=0;i<this.ancestors.length;i++){
			var ac=this.ancestors[i];
			ac.removeClass("flashNoMargin");
		}
		for(var j=0;j<this.ancestorSiblings.length;j++){
			var acSib=this.ancestorSiblings[j];
			if(acSib.hasClass("flashNoMargin")){
				acSib.removeClass("flashNoMargin");
			}else{
				acSib.removeClass("invisible");
			}
		}
	},
	
	getVisibleElements: function(){
		this.ancestors=[];
		this.ancestorSiblings=[];
		var visibleElements=[];
		var elem=this.swfContainer;
		while(elem!=$E('html')){
			var ancestor=elem;
			this.ancestors.push(ancestor);
			elem=elem.getParent();
			this.ancestorSiblings=this.ancestorSiblings.merge(elem.getChildren().remove(ancestor));
		}
		this.ancestors.push(elem);
	},
	
	getScrollBarWidth: function() {
        var inner = new Element('p').setStyles('width: 100%; height: 200px;');
        var outer = new Element('div')
            .adopt(inner)
            .setStyles('position: absolute; visibility: hidden; width: 200px; height: 150px; overflow: hidden')
            .injectInside(document.body);
        var w1 = inner.offsetWidth;
        outer.style.overflow = 'scroll';
        var w2 = inner.offsetWidth;
        if (w1 == w2) w2 = outer.clientWidth;     
        outer.remove();                            
        return (w1 - w2);
    },
	
	handleDocMouseWheel: function(delta){
		if(PAC.flexPreview&&this.oldPreview){
			if(PAC.flexPreview.setScroll)PAC.flexPreview.setScroll(delta);
		}
	},
	
	viewerInitialized: function(){
		debug.log('flash viewer initialized');
		this.resizeContent();
	},

	viewerOnLoadInit: function(){
		debug.log("loading flash document... ");
		this.resizeContent();
	},
	
	viewerOnLoadProgress: function(percentLoaded){
		debug.log(percentLoaded+" percent loaded")
	//	this.resizeContent(); 
	},

	viewerOnLoadComplete: function(){
		debug.log('loading document completed');
		this.swfCnt.addEvent("mouseover",this.onMouseOver.bind(this));
		this.swfCnt.addEvent("mousedown",this.onMouseDown.bind(this));
		//this.swfCnt.addEvent("blur",this.onBlur.bind(this));
		if(this.oldPreview){
			if(isMoz||isChrome){
				this.swfCnt.addEvent("DOMMouseScroll",this.onMouseWheel.bind(this));
			}else if(!isIE){
				this.swfCnt.addEvent("mousewheel",this.onMouseWheel.bind(this));
			}
			window.addEvent("resize",this.onWindowResize.bind(this));	// !important: add resize event listener function!
		}
		this.fireEvent("onDocumentComplete");
	},

	viewerOnUnloadComplete: function(){
		debug.log('successfully unloaded document');
		this.swfCnt.removeEvent("mouseover",this.onMouseOver.bind(this));
		this.swfCnt.removeEvent("mousedown",this.onMouseDown.bind(this));
		if(this.oldPreview){
			window.removeEvent("resize",this.onWindowResize.bind(this));	// !important: remove resize event listener function!
			if(isMoz||isChrome){
				this.swfCnt.removeEvent("DOMMouseScroll",this.onMouseWheel.bind(this));
			}else if(!isIE){
				this.swfCnt.removeEvent("mousewheel",this.onMouseWheel.bind(this));
			}
		}
	},

	viewerOnLoadError: function(httperrorcode, status){
		alert("error " + httperrorcode +"status "+ status);
	},
	
	getLocaleStr: function(p){
		var localeStr=$t(p.locID+"."+p.appID+"."+(p.itemID?p.itemID+".":"")+p.paramID);
		if(PAC.flexPreview){
			if(PAC.flexPreview.setLocaleStr)PAC.flexPreview.setLocaleStr(p,localeStr);
		}
	},
	
	setCurrSelection: function(currSel){
		if(currSel.selection){
		//	console.log("user selected text:\n"+currSel.text);
			this.currSelection=new TextSelection(
				currSel.text,
				currSel.selection.headCharIdx,
				currSel.selection.tailCharIdx,
				currSel.selection.headPageIdx,
				currSel.selection.tailPageIdx
			);
		}else{
		//	console.log("system selected text");
			this.currSelection=new TextSelection(
					currSel.text,
					currSel.headCharIdx,
					currSel.tailCharIdx,
					currSel.headPageIdx,
					currSel.tailPageIdx
				);
		}
		this.swfObj.addEvent("keyup",this.checkKey.bind(this));
//		var currSelectionText=$("selText");
//		$("headChar").setProperty("value",unescape(this.currSelection.headChar));
//		$("tailChar").setProperty("value",unescape(this.currSelection.tailChar));
//		$("headPage").setProperty("value",unescape(this.currSelection.headPage));
//		$("tailPage").setProperty("value",unescape(this.currSelection.tailPage));
//		currSelectionText.setProperty("value",unescape(this.currSelection.text));
	},
	
	selectText:function(headCharIdx,tailCharIdx,headPageIdx,tailPageIdx){
		if(PAC.flexPreview&&this.oldPreview){
			//PAC.flexPreview.setTextSelectionRange({"headCharIdx":headCharIdx,"tailCharIdx":tailCharIdx,"headPageIdx":headPageIdx,"tailPageIdx":tailPageIdx});
			//PAC.flexPreview.setCurrentZoom("page");
			//PAC.flexPreview.setCurrPage(headPageIdx);
		}
	},

	checkKey: function(event){
		if(event.ctrlKey){
			if(event.keyCode==67){
				CopyToClipboard(this.currSelection.text);
			}
		}
	},
	 
	setStatus: function(status){
		if(PAC.flexPreview){
			this.status=status;
			status.waiting?status.waiting=PACHelper.unescapeEntities(status.waiting):false;
			status.error?status.error=PACHelper.unescapeEntities(status.error):false;
			status.loading?status.loading=PACHelper.unescapeEntities(status.loading):false;
			if(PAC.flexPreview.setStatus){
				PAC.flexPreview.setStatus(status);
			}
		}
	},
	 
	setVersionID: function(id,reload){
		this.versionID=id;
		if(PAC.flexPreview){
			if(PAC.flexPreview.setVersionID){
				PAC.flexPreview.setVersionID(id,reload);	
			}
		}
		this.setStatus({currState:"loading"});
	},
	 	 
	setDocID: function(id){
		if(id!=this.docID){
			this.docID=id;
			if(PAC.flexPreview){
				if(PAC.flexPreview.setDocID)PAC.flexPreview.setDocID(id);
			}
		}
		this.setStatus({currState:"loading"});
	},
	 
	loadDoc: function(newRemote){
		if(PAC.flexPreview){
			if(newRemote){
				PAC.flexPreview.getRemoteDocument();
			}else{
				PAC.flexPreview.getDocument();
			}
		}
	}
	
}

);
FlexEmbed.implement(new PACEvents); // for global event dispatching

function getBrowserVersion(o){
	if(!o)o={};
	window.isMac=window.navigator.userAgent.indexOf("Macintosh")>-1;
	if(isMac)o.isMac=true;
	window.isSafari=window.navigator.userAgent.indexOf("Safari")>-1;
	if(isSafari)o.isSafari=true;
	window.isIE=window.navigator.userAgent.indexOf("MSIE")>-1;
	if(isIE)o.isIE=true;
	window.isOpera=window.navigator.userAgent.indexOf("Opera")>-1;
	if(isOpera)o.isOpera=true;
	window.isChrome=window.navigator.userAgent.indexOf("Chrome")>-1;
	if(isChrome)o.isChrome=true;
	window.isMoz=window.navigator.userAgent.indexOf("Mozilla")>-1&&!isSafari&&!isIE;
	if(isMoz)o.isMoz=true;
	window.isFF2=window.navigator.userAgent.indexOf("Firefox 2.0")>-1; 
	if(isFF2)o.isFF2=true;
	return o;
}

/**************** general viewport helper functions *****************/

/* cross browser event cancellation function */
function cancelDOMEvent(e)
{
  e = e ? e : window.event;
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
}