/**
 * (c) 2005 Primary Brokers S.A. - http://www.primary.com.ar/
 * Version 3
 */

/**
 * webstream-conn.js
 * Variables y metodos inherentes a la conexion http al server de Pushlets.
 * (c) 2006 Primary Brokers - http://www.primary.com.ar/
 */
	var lagTimeout=25000; // 15 seg
	var lagTime=0;
	var comCheck;
	var lastTime=0;
	var lastServerTime=0;
	var connMode="pull";
	var OrdersChannel="/worders";
	var QuotesChannel="/wquotes";
	var StatusChannel="/wstatus";
	var GraphChannel="/wgraph";
	var SystemChannel="/wsystem";
	var ObjectsChannel="/wobjects";
	var OrderResChannel="/worp";
	var SessionChannel= StatusChannel + "/sessions"
	var size=1;
	var listenAckID=null;
	var subscriptions = new Array();
        var connectionRetries=0;
        var maxConnectionRetries=3;

	/**
	 * Actualiza la fecha del ultimo evento
	 */
	function markEvent(event) {
		var now = new Date();
		lastTime = now.getTime();
		var tempForError = lastServerTime;
		if (event != null) {
			try {
				lastServerTime = event.get("p_time") * 1000;
			} catch (err) {
				lastServerTime = tempForError;
				top.ool.ErrorRaro="no pudo setear el p_time" + event;
				pstatus("Error seteando el tiempo: " + err);
			}
		} else {
			//porque 0??? va a reiniciar
			// TODO: Sacar esto.
			top.ool.ErrorRaro="El event vino null" + event;
			//lastTime=0;
			pstatus("El evento es null!");
		}
	};
	
	/**
	 * Cicla entre modo stream y modo pull.
	 * TODO: esto ya no se usa porque la version AJAX de Pushlets solo soporta pull.
	 */
	function toggleListenMode() {
		if (connMode == "stream") {
			connMode="pull";
		} else {
			connMode = "stream";
		}
		pstatus("connMode=" + connMode);
	};
	
	/**
	 * Chequea que la sesion anterior sea igual a la actual.
	 * Devuelve:
	 * 1: si la sesion es la misma
	 * 0: si la sesion es otra y realizo la
         */
//	function checkSession(id) {
		//if (!sessionId) {
			//pstatus("wsconn: sessionId null");
			//return -1;
		//} else if (sessionId != id) {
			//pstatus("wsconn: seteando sessionId " + id);
			//sessionId=id;
			//p_listen(QuotesChannel,connMode);
			//userManager.loggedin=1;
			//return 0;
		//} else if (listenAckID != id) {
			//pstatus("ERROR: checkSession: listenAckID no concuerda");
			//top.ool.logout();
			//return 1;
		//} else {
			//pstatus("wsconn: session correcta!");
			//return 1;
		//}
		//return -1;
	//}
			
	/**
	 * Realiza la conexion al server
	 */
	function connect() {
		pstatus("connect: connectionMode="+connMode);
		//PL.setDebug(true);
		p_join_listen();
	}

	function checkConnection() {
		var now = new Date();
		var time = now.getTime();
		lagTime = now - lastTime;
		//pstatus("checkConnection: now=" + time + ", last=" + lastTime +", lagTime=" + lagTime);
                if (lagTime > lagTimeout) {
                        if (connectionRetries < maxConnectionRetries) {
				try {
                                	connectionRetries++;
                               		pstatus("checkConnection: reintento " + connectionRetries);
                                	PL._doRequest("refresh","retry="+connectionRetries);
				} catch (err) {
					//alert("ERROR checkConnection: "+err);
				}
                        } else {
                                clearInterval(comCheck);
                                debug=0;
                                alert("Problemas en la conexion: " + lagTimeout/1000 + "s. Reconectando...");
                                top.ool.restartPushlet();
                                //top.x.location.reload();
                        }
                } else if (connectionRetries > 0) {
                        pstatus("checkConnection: limpiando connectionRetries");
                        connectionRetries=0;
                        debug=0;
                }
	}
	
	function onAbort(event) {
		pstatus("onAbort: " + event);
	}
	
	function onEvent(event) {
		markEvent(event);
		//pstatus("onEVENT: " + event);
	}
	
	function setDebugPushlet(Dat){
		p_setDebug(Dat);
	}
	/**
	 * Llama a login extrayendo los datos de un form.
	 * El form debe llamarse "formlogin" y los campos son
	 * "user" y "pass"
	 */
	function form_login() {
		var form = document.forms['loginform'];
		login(form.user.value,form.pass.value);
	}
	
	/**
	 * Se desconecta del servidor WebStream y recarga el 
	 * frame
	 */
	function logout() {
		p_leave();
		location.reload();
	}

	/**
	 * Envia un pedido de login al servidor WebStream 
	 */
	function login(user,pass) {
		pstatus("Login " + user);
		p_login(user,pass);
		pstatus("Login finish ");
	}
	
	function onNack(event) {
		pstatus("onNack" + event);
		try{
			if (event.get(iTags.REASON)=="authenticate: Exception: Error authenticating"){
				try {
					eventHandler.removeListener(null);
				}catch(err){}
				alert("Sesion invalida.\nProbablemente haya iniciado sesion desde otro equipo o su sesion fue expirada.");
				top.location.reload();
			} else {
				pstatus("onNack: " + event);
			}
		}catch(err){
			pstatus("ERROR onNack[" + event +"]: "+err );
		}
	}
	
	function onLoginAck(event) {
		markEvent(event);
		pstatus("Login ack! event=" + event);
		pstatus("Disparando refreshData");
		eventHandler.updateListeners(event);
		refreshSubs();
	}

	function refreshData() {
		if (userManager.loggedin >0) {
			p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESH,iTags.ACCOUNT,userManager.user);
		} else {
			p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESH);
		}
		pstatus("refresh enviado para el User: " + userManager.user );
		//pstatus("refresh pedido por " + refreshData.caller + " pero NO ENVIADO");
	}

	function sendRefreshTo(acc) {
		p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESH,iTags.ACCOUNT,acc);
		pstatus("refresh para " + acc  + " enviado");
	}
	function sendReloadAccount(acc) {
		p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_RISK_RELOAD_ACCOUNT,iTags.ACCOUNT,acc);
		pstatus("reload account para " + acc  + " enviado");
	}
	function refreshOperation(market,account){
		if (account==null){
			p_publish(OrdersChannel, iTags.TYPE, iTags.TYPE_REFRESHOPERATION, iTags.MARKET, market);
		}else{
			p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHOPERATION, iTags.ACCOUNT, account, iTags.MARKET, market);
		}
	}
	function refreshQuote(pid){
		//p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHQUOTE, iTags.PID, pid);
	}
	
	function refreshRisk(market,pid, acc){
                if (acc) {
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHRISK,iTags.ACCOUNT,acc, iTags.MARKET, market, iTags.PID, pid);
                }else if(userManager.loggedin>0){
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHRISK,iTags.ACCOUNT,userManager.user, iTags.MARKET, market, iTags.PID, pid);
                }else{
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHRISK, iTags.MARKET, market, iTags.PID, pid);
                }
	}
	
	function refreshSubs(acc){
                if (acc) {
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHSUBS,iTags.ACCOUNT,acc);
                }else if(userManager.loggedin >0){
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHSUBS,iTags.ACCOUNT,userManager.user);
                }else{
                        p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHSUBS);
                }
	}
	
	function onSubscribeAck(event) {
		try {
		var sid=event.get('p_sid');
		var subject=event.get('p_subject');
		subscriptions[sid]=subject;
//		pstatus("Listen ACK. sid=" + sid + ", subject=" + subject);
                var xx = subject.indexOf("/wrisk");
                if (xx >= 0){
			var arr = subject.split("/");
			var acc = arr[3];
			if (acc != null) {
                        	p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_REFRESHRISK,iTags.ACCOUNT,acc);
			}

                }
                var xxx = subject.indexOf(QuotesChannel);
		pstatus("subject=" + subject + ", xxx=" + xxx);
                if (xxx >= 0){
			// Es una subscripcion de quotes

			// El mercado viene despues de quoteschannel mas la barra.
			var mstart=xxx+QuotesChannel.length+1;	
			//pstatus("mstart=" + mstart);
			var mend=subject.indexOf("/",mstart);
			//pstatus("mend=" + mend);
			var market=subject.substring(mstart,mend);
			//pstatus("market=" + market);
			var pid=subject.substring(mend+1);	
			//pstatus("pid=" + pid);
                        refreshQuote(pid);
                }

		//var xxxx = subject.indexOf(OrderResChannel);
                //if (xxxx >= 0){
		//	var arr2 = subject.split("/");
		//	var mkt=arr2[2];
		//	var acc
		//	try {
		//		if (arr2[3].length>0){
		//			acc=arr2[3];
		//		}else{
		//			acc=null;
		//		}
		//	}catch (err){
		//		acc=null;
		//	}
		//	refreshOperation(mkt,acc);
		//	pstatus("RefreshOp enviado: mkt=" + mkt + " acc=" + acc);
		//}
		eventHandler.onData(event);

		} catch (err) {
			pstatus("listenAck: " + event +"\nerror="  + err);
		}
	}	
        function onJoinAck(event) {		 
		markEvent(event);
		listenAckID=event.get('p_id');
		eventHandler.updateListeners(event);
		pstatus("Join Ack. id=" + listenAckID + ". Enviando Refresh... ");
		comCheck = setInterval("checkConnection()",5000);
		setTimeout("refreshSubs()",1000);
        }

	// onData method called by pushlet frame
	function onData(pushletEvent) {
		markEvent(pushletEvent);
		try {
			eventHandler.onData(pushletEvent);
		} catch (err) {
			pstatus("webstream-conn.onData: ERROR="+err);
		}
	}
	
	function take(pid) {
		var p = productManager.getProduct(pid);	
		var price = p.askPrice ? p.askPrice : p.lastPrice;
		p_publish(OrdersChannel,"mkt",p.market,iTags.TYPE,iTags.TYPE_ORDER,iTags.PID,pid,iTags.PRICE,price,iTags.SIZE,size,iTags.ACTION,iTags.ACTION_TAKE);
	}

	function hit(pid) {
		var p = productManager.getProduct(pid);	
		var price = p.bidPrice ? p.bidPrice : p.lastPrice;
		p_publish(OrdersChannel,"mkt",p.market,iTags.TYPE,iTags.TYPE_ORDER,iTags.PID,pid,iTags.PRICE,price,iTags.SIZE,size,iTags.ACTION,iTags.ACTION_HIT);
	}

