import java.io.*;
import java.net.*;
import java.util.*;

class conexion extends Thread
{
	String clientSentence;
	String capitalizedSentence;
	boolean conexion = true ;
	String close = "close";
	Vector calculadoras = new Vector();	
	String total;
	Socket connectionSocket;

	public conexion (Socket connectionSocket,Vector calculadoras) throws Exception
	{
		this.connectionSocket= connectionSocket;
		this.calculadoras = calculadoras;
	}

	public void run()
	{
		while(conexion)
		{
		
			try
			{
				BufferedReader inFromClient = new BufferedReader(new InputStreamReader(this.connectionSocket.getInputStream()));
		      DataOutputStream  outToClient = new DataOutputStream(this.connectionSocket.getOutputStream());
				conexion = true;
				while (conexion)
				{
		 			clientSentence = inFromClient.readLine();
				  	if(close.compareTo(clientSentence)==0)
				   {
						conexion = false ;
					   connectionSocket.close();
			   	}
				   else
				   {
						StringTokenizer st = new StringTokenizer(clientSentence,"*/+-",true);
			   		total  = numeraliza(st,calculadoras);
			       	capitalizedSentence = total;
					   capitalizedSentence = capitalizedSentence + '\n';
		            outToClient.writeBytes(capitalizedSentence);
			   	}
			   }
			}
			catch(IOException e)
			{
			}
		}
	}

	//metodo para identificar los operadores y  guardarlos en un vector
	static String numeraliza(StringTokenizer st,Vector calculadoras)
   {
		//creamos un entero con e
		double[] numeros = new double[(int)(st.countTokens())];
	 	String[] operadores =new String[(int)(st.countTokens())];
		String resultado = "0";
		int num = st.countTokens();
	 	double numero=0;
	 	double num_aux =0;
	 	int num_cont=0;
	 	int ope_cont=0;
	 	int i,j,c;
	 	boolean elanteriorfuenumero=false;
	 	boolean noerror = true;
	 	boolean ok  = false;
	 	String X;
	 	String resta = "-";
	 	String suma ="+";
	 	String multi = "*";
	 	String div = "/";
	 	boolean calculoencotrado;
	 	if(st.countTokens() < 1)
	 	{
			i = num;
			System.out.println("\n Envio un salto de linea");
			resultado = "none";
  	      noerror = false;
	 	}
		//Inicio I, revisión de los numeros y operadores , tambien se guardan en un arreglo cada 1
		for( i=0 ; (i < num) && noerror;i++)
		{
			X = (st.nextToken());
			//System.out.printf("\n" +i+"Entro = "+X+"");
			if((X.compareTo("+")==0)||(X.compareTo("-")==0)||(X.compareTo(div)==0)||(X.compareTo(multi)==0))
			{
				//System.out.printf("\nOperador= "+X+"");
				operadores[ope_cont] = X;
				ope_cont++;
				if(!elanteriorfuenumero || (i == num -1))
				{
					i = num;
					//System.out.println("\nERROR con operadores");
				   resultado = "none";
           		noerror = false;
				}
				elanteriorfuenumero = false;
			}
			else
			{
				try
				{
					numero = Double.parseDouble(X.trim());
				}
				catch (NumberFormatException nfe) 
				{
    				//System.out.println("ERROR en el numero " + nfe.getMessage());
           		resultado = "none";
           		i = num;
           		noerror = false;
           		return resultado;
           	 }
             if(noerror)
             {
				 	if(elanteriorfuenumero)
					{
						i = num;
		    			//System.out.println("\nERROR con numeros");
						resultado = "none";
           			noerror = false;
					}
					if(noerror)
					{
						//System.out.printf("\n  numero = "+numero+" ");
				    	numeros[num_cont] = numero;
						num_cont++;
						elanteriorfuenumero = true;
					}
				}
			}
		}
     //Fin I
	  //llamado del la funcion reorder, para la
		if(noerror)
		{
	 		//Inicio II, se hace que las diviciones se envien a una calculadora
			calculoencotrado = false;
			for( i = 0 ; i < ope_cont;i++)
	 		{
				if(((String)operadores[i]).compareTo(div)==0)
				{
		 			//num_aux=(double)numeros[i] /(double)numeros[i+1]; //Esto se tiene que cambiar para que lo aga otro geton
		 			for(c=0;c < calculadoras.size();c++)
		 			{
						if((!calculoencotrado)&&(!((conexioncalc)calculadoras.elementAt(c)).busy) && (((conexioncalc)calculadoras.elementAt(c)).conectado))
						{
							resultado = ((conexioncalc)calculadoras.elementAt(c)).calculasend(""+ numeros[i] +"/"+ numeros[i+1] +"");
							if(resultado.compareTo("Error")!=0)
							{
								calculoencotrado = true;
								num_aux = Double.parseDouble(resultado);
							}
						}
		 			}
		 			if(!calculoencotrado)
		 			{
						resultado="noneD";
						return resultado;
		 			}
					numeros[i]=num_aux;
					System.out.printf("\n Una division Resp:"+num_aux+" ");
					for(j= i + 1 ; j < num_cont-1;j++)
		 			{
						numeros[j] = numeros[j+1];
					}
		 			num_cont--;
		 			if(i < ope_cont-1)
		 			{
		 				operadores[i]=operadores[i+1];
		 		 		for(j= i + 1 ; j < ope_cont-1;j++)
		 		 		{
		 			 		operadores[j] = operadores[j+1];
		 		 		}
					}
	 	 			ope_cont--;
					i--;
				}
	 		}
			//Fin II
	 		//INICIO III para multiplicacion
	 		for( i = 0 ; i < ope_cont;i++)
	 	 	{
	 			if(((String)operadores[i]).compareTo(multi)==0)
	 			{
	 				//num_aux=(double)numeros[i] * (double)numeros[i+1]; //Esto se tiene que cambiar para que lo aga otro geton
	 		 		for(c=0;c < calculadoras.size();c++)
			 		{
			 			if((!calculoencotrado)&&(!((conexioncalc)calculadoras.elementAt(c)).busy) && (((conexioncalc)calculadoras.elementAt(c)).conectado))
			 			{
			 				resultado = ((conexioncalc)calculadoras.elementAt(c)).calculasend(""+ numeros[i] +"*"+ numeros[i+1] +"");
			 				if(resultado.compareTo("Error")!=0)
			 				{
			 					calculoencotrado = true;
			 					num_aux = Double.parseDouble(resultado);
			 				}
			 			}
			 		}
			 		if(!calculoencotrado)
			 		{
			 			resultado="noneD";
			 			return resultado;
		 			}
					numeros[i]=num_aux;
					System.out.printf("\n Una Multiplicacion resp:"+num_aux+" ");
	 		 		for(j= i + 1 ; j < num_cont-1;j++)
	 		 		{
	 			 		numeros[j] = numeros[j+1];
	 		 		}
	 		 		num_cont--;
	 		 		if(i < ope_cont-1)
	 		 		{
	 		 			operadores[i]=operadores[i+1];
	 		 		 	for(j= i + 1 ; j < ope_cont-1;j++)
	 		 		 	{
	 		 			 	operadores[j] = operadores[j+1];
	 		 		 	}
		 	 	 	}
	 	 	 		ope_cont--;
	 				i--;
	 			}
			}
	 		//FIN 3
	 		//INICIO IV suma y resta
	 		for( i = 0 ; i < ope_cont;i++)
	 		{
				ok = false;
				calculoencotrado = false;
	 	 		if(((String)operadores[i]).compareTo("+")==0)
	 	 		{
	 	 			//num_aux=(double)numeros[i] + (double)numeros[i+1]; //Esto se tiene que cambiar para que lo aga otro geton
					System.out.println(" Suma  size"+calculadoras.size()+"");
	 	 		 	for(c=0;c < calculadoras.size();c++)
					{
						System.out.println(" IN "+!calculoencotrado+"  "+(!((conexioncalc)calculadoras.elementAt(c)).busy) +"  "+(((conexioncalc)calculadoras.elementAt(c)).conectado) + " ");
						if((!calculoencotrado)&&(!((conexioncalc)calculadoras.elementAt(c)).busy) && (((conexioncalc)calculadoras.elementAt(c)).conectado))
				 		{
				 			resultado = ((conexioncalc)calculadoras.elementAt(c)).calculasend(""+ numeros[i] +"+"+ numeros[i+1] +"");
							System.out.println(" IN "+c+" "+resultado +" ");
				 			if(resultado.compareTo("Error")!=0)
				 			{
								calculoencotrado = true;
				 				num_aux = Double.parseDouble(resultado);
				 			}
				 		}
				 	}
				 	if(!calculoencotrado)
				 	{
						System.out.println(" IN2 "+c+"");
				 		resultado="noneD";
				 		return resultado;
		   		}
			 	 	numeros[i]=num_aux;
	 	 			System.out.printf("\n Resp :"+num_aux+" ");
	 	 		 	for(j= i + 1 ; j < num_cont-1;j++)
	 	 		 	{
	 	 				numeros[j] = numeros[j+1];
	 	 		 	}
	 	 		 	num_cont--;
	 	 		 	if(i < ope_cont-1)
	 	 		 	{
	 	 		 		operadores[i]=operadores[i+1];
	 	 		 		for(j= i + 1 ; j < ope_cont-1;j++)
	 	 		 		{
	 	 		 			operadores[j] = operadores[j+1];
	 	 		 		}

	 	 	 	 	}
	 	 	 	 	ope_cont--;
	 	 			i--;
	 	 			ok = true;
	 	 		}
	 	 		if(!ok)
	 	 		{
					System.out.println("Una resta de "+numeros[i]+" Y "+numeros[i+1]+" ");
					//num_aux=(double)numeros[i] - (double)numeros[i+1]; //Esto se tiene que cambiar para que lo aga otro geton
				   for(c=0;c < calculadoras.size();c++)
				   {
						if((!calculoencotrado)&&(!((conexioncalc)calculadoras.elementAt(c)).busy) && (((conexioncalc)calculadoras.elementAt(c)).conectado))
						{
					 		resultado = ((conexioncalc)calculadoras.elementAt(c)).calculasend(""+ numeros[i] +"-"+ numeros[i+1] +"");
					    	if(resultado.compareTo("Error")!=0)
							{
					    		calculoencotrado = true;
								num_aux = Double.parseDouble(resultado);
							}
						}
				 	}
				   if(!calculoencotrado)
				   {
						resultado="noneD";
						return resultado;
		   		}
		 	 		numeros[i]=num_aux;
					System.out.printf("\n Respuesta :"+num_aux+" ");
					for(j= i + 1 ; j < num_cont-1;j++)
					{
						numeros[j] = numeros[j+1];
					}
					num_cont--;
					if(i < ope_cont-1)
					{
						operadores[i]=operadores[i+1];
					 	for(j= i + 1 ; j < ope_cont-1;j++)
					 	{
					 		operadores[j] = operadores[j+1];
					 	}
		 	 	 	}
					ope_cont--;
					i--;
	 	 		}
	    	}
		}
		resultado = ""+numeros[0]+"";
		//FIN SUMA Y RESTA
		System.out.printf("\n Resultado "+resultado+" ");
	 	return resultado;
	}
}