//utility methods:---------------------------------------------------------

/**
* add an event listener to an object.
**/
function addEvent(obj, evType, fn){ 
	if (obj.addEventListener){ 
		obj.addEventListener(evType, fn, false); 
	} else if (obj.attachEvent){ 
		obj.attachEvent("on"+evType, fn); 
	} else {
		var old = obj['on'+evType];
		if (typeof obj['on'+evType] != 'function') {
			obj['on'+evType] = fn;
		} else {
			obj['on'+evType] = function() {
			if (old)
				old();
			fn();
			}
		}
	} 
}


/**
* load a script 
**/
function loadScript(url){
// this implementation is sure to work before page completed loading.
   document.write('<script src="', url, '" type="text/JavaScript"><\/script>');
}

/**
* after the page is loaded, we can replace loadScript to a more civilized implementation.
**/
addEvent(window, 'load',function(){
	loadScript = function(url){
		var th = document.getElementsByTagName('head')[0];
		var s = document.createElement('script');
		s.setAttribute('type','text/javascript');
		s.setAttribute('src',url);
		th.appendChild(s);
	}
});

//initiation:----------------------------------------
//this is the main bavailable objects and methods repository.
var BA = new Object();
BA.location = location.protocol+'//www.bavailable.com/ba_generic/';
// load the following scripts:
try{
	BA.country = localCountry;
} catch(e){
	loadScript(BA.location+'setCountryByGeoLocationIP.js.php');
}
/*
try {
	//use hard-coded server IP if defined
		BA.VOIPServer = localServerIP;
} catch(e) {
	loadScript(BA.location+'setServerByGeoLocationIP.js.php');
}
*/

loadScript(BA.location+'unConverted.js');
loadScript(BA.location+'Coordinates.js');
loadScript(BA.location+'PlaceHolder.js');
loadScript(BA.location+'PositionParams.js');
loadScript(BA.location+'InitiatorManager.js');

/**
* alert before navigating out of page while on call.
**/
function reallyExit() {
	try{
		if (BA.openInitiator.isOnCall()){ 
			var position = getAnchorPosition(BA.openInitiator.initiatorDiv); 
			window.scrollTo(position.x, position.y);// the better way
			BA.openInitiator.initiatorDiv.scrollIntoView(); // for IE7
			return 'You are about to get disconnected, please press the pop-up button to continue in another window.';
		}
	} catch (e){}
	if (oldOnbeforeunload != null)
		return oldOnbeforeunload();
};
// don't try to replace the next two lines with addEvent(),
// this is a special kind or event... it needs a firm hand.
var oldOnbeforeunload = window.onbeforeunload;
window.onbeforeunload = reallyExit;

//the most common style of the divs we create with setDivstyle:
BA.DivStyle = {
	defaults:{
		direction:'ltr',
		textAlign:'left',
		display:'block',
		overflow:'hidden',
		position:'relative',
		margin:'0px',
		padding:'0px'
	},
	//list of properties (measured in pixles) that we support in setDivstyle:
	optionalPX:['width', 'height', 'top', 'left', 'right'],
	//list of properties that we support in setDivstyle, not measured in pixles:
	optional:['zIndex', 'visibility']
}
/**
* formats the style argument by a combination of default and supplied properties.
**/
function setDivstyle(styleObj, measuresObj){
	for (prop in BA.DivStyle.defaults){
		if (measuresObj[prop] != null)
			styleObj[prop] = measuresObj[prop];
		else
			styleObj[prop] = BA.DivStyle.defaults[prop];
	}
	for (propIndex in BA.DivStyle.optionalPX){
	var prop = BA.DivStyle.optionalPX[propIndex];
		if (measuresObj[prop] != null)
			styleObj[prop] = measuresObj[prop]+'px';
	}
	for (propIndex in BA.DivStyle.optional){
	var prop = BA.DivStyle.optional[propIndex];
		if (measuresObj[prop] != null)
			styleObj[prop] = measuresObj[prop];
	}
}
//make widget methods: --------------------------------------------------
// notice: widgets are created in memory, and are inserted to the page after it window.onload event.

//the contract of BA.openInitiator:
// BA.openInitiator will point to the single active instance of InitiatorManager at all times.
// if no initiator is active (= displayed on screen), then BA.openInitiator should be either null or undefined.

/**
* make an inline widget that looks like an image.
* this widget will open an initiator when clicked on.
* customerId : the id of the customer
* customerEntityId : the id of the widget in the customer's scope
* lang : the language of the initiator's UI (for now only Heb and En are available)
* calloutDirection : the position of the initiator relative to the widget
* url : the url of the image to display
* extraParams : (optional) optional extra parameters to add to the flash files URL (initiator AND dummyinitiator) such as stealCall, autoCall etc.
**/
function bavailable_makeImageWidget(customerId, customerEntityId, lang, calloutDirection, url, extraParams) {

	 loadScript(BA.location+'exposures.php?customerId='+customerId+"&customerEntityId="+customerEntityId);
    var img = document.createElement('img');
    img.id = 'ba_widget_'+customerEntityId;
    img.src = url;
    img.border = 0;
    img.className="bavailable_imageClass";
	 img.style.cursor="hand";
    addEvent(img,'click',function(){
		if(BA.openInitiator){
			if (BA.openInitiator.isOnCall()) return;
			BA.openInitiator.close();
		}
        BA.openInitiator = new InitiatorManager(customerId, customerEntityId, lang, calloutDirection, extraParams);
		document.body.style.cursor= "wait";
		var coordinates = BA.PositionParams[calloutDirection].processPosition(img);
        var div = BA.openInitiator.makeEnclosingDiv(coordinates.x, coordinates.y);//TODO: update this
		BA.openInitiator.close = 
			function(){
				document.getElementsByTagName('body')[0].removeChild(div);
			}
        document.getElementsByTagName('body')[0].appendChild(div);
		cursorWaitsUntilInitiatorLoads(BA.openInitiator);
    });
   new PlaceHolder(img).here();
}

/**
* async method, returns immediately.
* periodicly checks the loading status of the open initiator.
* when done loading (or if an exception occures) returns the cursor to default form.
**/
function cursorWaitsUntilInitiatorLoads(manager){
	var restoreCursorTimeoutId = null;
	restoreCursorTimeoutId = setInterval(function(){
		try {
			var dummyLoaded = manager.dummyDiv.firstChild.PercentLoaded();
			var initiatorLoaded = manager.initiatorDiv.firstChild.firstChild.PercentLoaded();
			if (dummyLoaded + initiatorLoaded == 200) {
				clearInterval(restoreCursorTimeoutId);
				document.body.style.cursor= "default";
			}
		} catch (e) {
			clearInterval(restoreCursorTimeoutId);
			document.body.style.cursor= "default";
		}
	}, 333);
}

/**
* make a widget of a static initiator.
* customerId : the id of the customer
* customerEntityId : the id of the widget in the customer's scope
* lang : the language of the initiator's UI (for now only Heb and En are available)
* top : location of the initiator, from top
* left : location of the initiator, from left
* extraParams : (optional) optional extra parameters to add to the flash files URL (initiator AND dummyinitiator) such as stealCall, autoCall etc.
**/
function bavailable_makeStaticWidget(customerId, customerEntityId, lang, top, left, extraParams){
	var manager = new InitiatorManager(customerId, customerEntityId, lang, -1, extraParams);
	manager.close = function(){
		window.close();
	}
	var div = manager.makeEnclosingDiv(left, top);
	addEvent(window,'load',function(){
		BA.openInitiator = manager;
	});
	new PlaceHolder(div).here();
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}
function bavailable_cornerCorrect() {
	var div=document.getElementById("ba_corner_floater");
	if(div==null)
		return;
	var y=f_scrollTop();
	div.style.top=y+"px";
}
/**
* make a widget of a corner image.
* this widget will open an initiator when clicked on.
* customerId : the id of the customer
* customerEntityId : the id of the widget in the customer's scope
* lang : the language of the initiator's UI (for now only Heb and En are available)
* type : visual type of the widget.
* extraParams : (optional) optional extra parameters to add to the flash files URL (initiator AND dummyinitiator) such as stealCall, autoCall etc.
**/
function bavailable_makeCornerWidget(customerId, customerEntityId, lang, type, extraParams){
	var div = document.createElement('div');
	div.id="ba_corner_floater";
	setDivstyle(div.style, {zIndex:1000000, position:'absolute', top:0, right:0});
   var img = document.createElement('img');
   img.id = 'ba_widget_'+customerEntityId;
   img.src = 'http://www.bavailable.com/bavailable_corner_button_'+type+'.png';
   img.border = 0;
	addEvent(img,'click',function(){
		BA.openInitiator = new InitiatorManager(customerId, customerEntityId, lang, -1, extraParams);
		document.body.style.cursor= "wait";
		div.removeChild(img);
		div.appendChild(BA.openInitiator.dummyDiv);
		div.appendChild(BA.openInitiator.initiatorDiv);
		BA.openInitiator.close = function(){
			div.appendChild(img);
			div.removeChild(BA.openInitiator.dummyDiv);
			div.removeChild(BA.openInitiator.initiatorDiv);
		}
		cursorWaitsUntilInitiatorLoads(BA.openInitiator);
	});
	div.appendChild(img);
	new PlaceHolder(div).here();
	setInterval("bavailable_cornerCorrect()", 100);
}

// utility functions:----------------------------------------------
// These functions are usually called by the flash initiator (or initiatordummy).
// their implementation is basically calling the parallel method in the initiator manager.
// they are using BA.openInitiator to locate the target initiator.
// that limits us to only one open initiator per page if we want these functions to work correctly,
// but makes these functions more robust (can be called by hosting page, without knowing what initiator is currently open).
// however, the flash can call the method in the initiator manager directly by using BA.initiators[id] expression. 
// this should allow for multiple initiators in the same page (not tested), but also has the potential of much chaos in debugging.

/**
* resize the open initiator and inner initiator divs to correctly view the initiator UI or the flash settings window.
**/
function bavailable_statusSettings(enterOrExit) {
	BA.openInitiator.statusSettings(enterOrExit);
}

/**
* open bavailable homepage.
**/
function bavailable_home() {
   window.open("http://www.bavailable.com/");
}

/**
* close initiator.
**/
function bavailable_close(){
	BA.openInitiator.close();
	BA.openInitiator = null;
}

/**
* return true if initiator is loaded, false if not.
**/
function bavailable_isLoaded(){
	try{
		return (BA.openInitiator)? 'true' : 'false';
	} catch(e){
		return 'false';
	}
}
/**
* open an LM chat and close initiator.
**/
function bavailable_chat(){
/*
	if (BA.openInitiator.isChatAvailable){
		var manager = BA.openInitiator;
		bavailable_close();
		manager.chat();
	}
*/
}
/**
* opens initiator in a new window.
* callId : (optional) if present, specifies that the new initiator should steal an ongoing call of the existing one.
**/
function bavailable_popup(callId){
	var url = BA.location+'InitiatorPopup.php?lang='+BA.openInitiator.lang;
	if (callId) //stealing a call.
		url += '&stealCall='+callId;
	url += '&customerId='+BA.openInitiator.customerId;
	url += '&customerEntityId='+BA.openInitiator.customerEntityId;
	url += '&localServerIP='+BA.VOIPServer;
	window.open(url, 'win',
		'directories=no,copyhistory=no,toolbar=No,width=305,height=330,MenuBar=No,location=No,scrollbars=No,status=No,resizable=No,fullscreen=No');
	if (!callId) //not stealing call, so close old initiator immediately.
		bavailable_close();
}

function bavailable_openWidgetFromImage(image, customerId, customerEntityId) {
	BA.country="US";
	if(BA.openInitiator) {
		if (BA.openInitiator.isOnCall()) 
			return;
		BA.openInitiator.close();
	}
	BA.openInitiator = new InitiatorManager(customerId, customerEntityId, "En", 1, new Object());
	document.body.style.cursor= "wait";
	var coordinates = BA.PositionParams[1].processPosition(image);
   var div = BA.openInitiator.makeEnclosingDiv(coordinates.x, coordinates.y);//TODO: update this
	BA.openInitiator.close = 
		function() {
			document.getElementsByTagName('body')[0].removeChild(div);
		};
   document.getElementsByTagName('body')[0].appendChild(div);
	cursorWaitsUntilInitiatorLoads(BA.openInitiator);
}


