/**
 * (c) 2005 Primary Brokers S.A. - http://www.primary.com.ar/
 */
function OrderManager (){
	this.orders = new Array();
	this.oids = new Array();
	this.debug=1;
	this.orderSender=this;
	/**
	 * determina si ya se envio refresh alguna vez.
	 */
	this.updated=false;
	this.name="OrderManager";
	eventHandler.addListener(this);
	
	this.subscribeORP=function() {
		try {
		var accs= userManager.listActiveAccounts();
		for (i in accs) {
			var x = accs[i];
			var subject="";
			if (userManager.isbroker) {
				subject="/worp/"+x[1]+"/"+ x[2];
			} else {
				subject="/worp/"+x[1]+"/"+ x[2] + "/"+x[0];
			}
	                this.log("p_subscribe: " + subject );
			p_subscribe(subject);
		}
		} catch (e) {
			this.log("ERROR: subscribeORP: " + e );
		}
	};

	this.makeOrder=function(pid,action,asize,pricepos) {
		var p = productManager.getProduct(pid);
		var price = 0;
		if ((pricepos > 0)){	
			price = pricepos;
		}
		if (p.lastPrice != 0){
			price=p.lastPrice;
		}
		if (action == iTags.ACTION_HIT && p.bidPrice != 0) {
			price=p.bidPrice;
		} else if (action == iTags.ACTION_TAKE && p.askPrice != 0) {
			price=p.askPrice;
		}
		var osize=size;
		if (asize) {
			osize=asize;
		}
		this.sendOrder(pid,p.market,price,osize,action);
	};

		
	this.getNextOID=function() {
		return Math.floor(Math.random()*50000);
	}
	this.sendCancelOrder=function(oid, account){	
		var estado = 0;
		try {
			var orden = this.getOrder(oid);
			pstatus ("Estado de la orden= " + orden.status);
			if ((orden.status == 1)||(orden.status == 4)||(orden.status == 5)){
				pstatus ("No envio en cancel= Por el estado de la orden no se puede cancelar");
				return 0;
			}
			estado = this.sendCancelOrderFunction(oid, account);
		}catch (err){
			pstatus("sendCancelOrder: ERROR=" + err);
			this.orderSender=this;
			estado = this.sendCancelOrderFunction(oid, account);
		}
		return estado;
	}
	this.sendCancelOrderFunction=function(oid, account){
		this.log("sendCancelOrder: "+oid+"|"+account);
                if (account){
                        p_publish(OrdersChannel,iTags.TYPE,iTags.ACTION_CANCEL,iTags.OID,oid,iTags.ACCOUNT,account);
			return 1;	
                }else{
                        pstatus("ERROR= sendCancelOrderFunction -> account=null");
			return 0;
                }
	}
	this.sendOrder=function(pid,market,price,size,action) {
		try {
			this.orderSender.sendOrderFunction(pid,market,price,size,action);
		} catch (err) {
			pstatus("sendOrder: ERROR=" + err); 
			this.orderSender=this;
			this.sendOrderFunction(pid,market,price,size,action);
		}
	}
	this.sendOrderFunction=function(pid,market,price,size,action,account) {
		if (!(account)){
			account = productManager.getAccount(pid);
		}
		var broker = productManager.getProduct(pid).broker;
		this.log("sendOrder: "+pid+"|"+market+"|"+price+"|"+size+"|"+action+"|"+account+"|"+broker);
		var cloid=this.getNextOID();
		if (account){
			p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_ORDER,"cloid",cloid,iTags.PID,pid,iTags.MARKET,market,iTags.PRICE,price,iTags.SIZE,size,iTags.ACTION,action,iTags.ACCOUNT,account,iTags.BROKER,broker);
		}else{
			p_publish(OrdersChannel,iTags.TYPE,iTags.TYPE_ORDER,"cloid",cloid,iTags.PID,pid,iTags.MARKET,market,iTags.PRICE,price,iTags.SIZE,size,iTags.ACTION,action);
		}
		try{
			top.ool.ordertable.UpdateCreate(this.createOrder(cloid,pid,market,price,size,action,account));
//			top.ool.ordertable.UpdateCreate(cloid); 
		}catch(err){
			this.log("Error Ups: "  + err)
		}
		return cloid;
	}
	this.listOrders=function(){
		var ret = new Array();
		for (i in this.orders) {
			ret.push(""+i);	
		}
		return ret.sort();
	};
	this.updateStatus=function(oid, estado){
		if (this.containsOrder(oid)) {
			this.orders[oid].status=estado;
			return this.orders[oid].status;
		}else{
			this.log("updateStatus: La orden " + oid + " no existe" );
			return 0;
		}
	};
	this.getOrder=function(oid) {
		if (this.containsOrder(oid)) {
			return this.orders[oid];
		} else {
			return this.addOrder(oid,null,null);
		}
	};
	this.createOrder=function(cloid,pid,market,price,size,action,account){
		var prod = productManager.getProduct(pid);
		var order = new Order();
		var now = new Date();
                lastTime = now.getTime();
		order.oid="-";
                order.pid=pid;
                order.mkt=market;
		if (prod) {
                	order.pri=prod.formatPrice(price);
		} else {
                	order.pri=price;
		}
                order.siz=size;
                order.act=action;
                order.ostatus=iTags.STATUS_PENDING; 
                order.fill_qty=0;
                order.p_time=lastTime;
                order.cloid=cloid;
                order.xml="";
		order.i_filled=false;
                order.acc =account;
		return order;
	
	};	
	this.addOrder=function(oid,pid,market) {
		var o = new Order(oid);
		o.pid=pid;
		o.market=market;
		this.orders[oid]=o;
		var l = this.orders.length;
		this.log("agregando [" + oid + "]: " + o);
		return o;
	};

	this.onData=function(event) {
		if (event.get(iTags.TYPE) == iTags.TYPE_ORDER_RESPONSE) {
			this.log("llego response=" + event);
			var pid=event.get(iTags.PID);
			var prod = productManager.getProduct(pid);
			if (prod == null) {
				// Polemico: Es una orden de un producto que no tenemos listado.
				// Por decision unanime (jsc), no muestro la orden.
				this.log("El producto de la orden no esta. La ignoro.");
				return;

			}
			var oid= event.get(iTags.OID);
			var order = this.getOrder(oid);
			order.pid=pid;
			order.market= event.get(iTags.MARKET);
			order.price= prod.formatPrice(event.get(iTags.PRICE));
			order.size= event.get(iTags.SIZE);
			order.action= event.get(iTags.ACTION);
			order.status= event.get(iTags.ORDER_STATUS);
			order.fill= event.get(iTags.FILL_QTY);
			try {
				if (event.get(iTags.TIME)!= null){
					order.time= event.get(iTags.TIME);
				}else{
					order.time= event.get("p_time");
				}
				
			}catch (err){
				order.time= event.get("p_time");
			}
			try {
				if (event.get(iTags.TEXT)!= null){
					order.text= event.get(iTags.TEXT);
				}
			}catch (err){
				order.text= err;
			}
			order.cloid= event.get("cloid");
			order.xml= event.xml;
			this.log("XML seteado" + order.xml);
			order.account = event.get(iTags.ACCOUNT);
		} else if (event.get(iTags.TYPE) == iTags.TYPE_POSITION) {
			if (this.updated) 
				return;

			this.subscribeORP();

			if (userManager.isbroker) {
				p_publish(OrdersChannel, iTags.TYPE, iTags.TYPE_REFRESHOPERATION, iTags.BROKER, userManager.brokerID);
			} else {
				var accs= userManager.listAccounts();
				for (i in accs) {
					var a = accs[i];
					p_publish(OrdersChannel, iTags.TYPE, iTags.TYPE_REFRESHOPERATION, iTags.ACCOUNT, a);
				}
			}
			this.updated=true;
		}
	};

	this.log=function(msg) {
		if (this.debug) {
			pstatus("OrderManager: " + msg);
		}
	};
	
	this.containsOrder=function(oid) {
		for (var p in this.orders) {
			if (p==oid) {
				return true;
			}
		}
		return false;
	};

	this.removeOrder=function(oid) {
		if (this.orders[oid]) {
			this.orders.splice(oid,1);
		}
	};
}

function Order(oid) {
	this.account="";
	this.oid=oid;
	this.pid=null;
	this.time=null;
	this.market="";
	this.type="";
	this.price="";
	this.size="";
	this.fill="";
	this.status="";
	this.cloid=0;
	this.xml="";
	this.text="";
	this.can="<img src='images/cancel.gif'>";
	this.toString=function() {
		return "Order " + this.oid + ", cloid="+this.cloid+", pid=" + this.pid + ", market=" + this.market + ", status=" + this.status +", price=" + this.price + ", size="+this.size + ", fill="+this.fill+", text="+this.text;
	};
};

function sortOrders(a,b) {
	var aid=orderManager.getOrder(a).oid;
	var bid=orderManager.getOrder(b).oid;
	var res = aid - bid;
	if (res ==0) return a-b;
	return res;
}

