package com.linx.dposandroid;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Bundle;
import android.text.InputFilter;
import android.view.View;
import android.widget.Button;
import android.view.Menu;
import android.widget.EditText;
import android.widget.TextView;
import com.linx.dtefmobile.*;
import android.util.Log;
import android.os.AsyncTask;

public class CPOS extends Activity {
	static boolean bSocketAberto;
	boolean bChegaramDados;
	char[] buffer = new char[2];	
  Socket socket;    
  String inputData = null;   
  String sIP;
  int iPorta;
  String sDadosComando;
  
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    Intent i = getIntent();
    Bundle extras = i.getExtras();

    Log.v("CPOS", "Create");

    String action = extras.getString("action");
    String parameters = extras.getString("parameters");
    if (action.equals("comandoPOS"))
    {
      comandoPOS(parameters);
    }
  }

  public void DefineParametrosDTEFMobile(CDTEFMobile oDTEFMobile, String parameters)
  {
    String[] pars = parameters.split(";");
    for (int i = 0; i < pars.length; i++)
    {
      String par = pars[i];

      String[] keyvalues = par.split("=");
      String key = keyvalues[0];
      String value = keyvalues[1];

      Log.v("DefineParametrosDTEFMobile", "key=" + key + " - value=" + value);
      oDTEFMobile.setParameter(key, value);
    }
  }

  public String ValorParametro(String parameters, String parameter)
  {
    Log.v("ValorParametro", "parameters=" + parameters + " - parameter = " + parameter);

    String[] pars = parameters.split(";");
    for (int i = 0; i < pars.length; i++)
    {

      String par = pars[i];

      String[] keyvalues = par.split("=");
      String key = keyvalues[0];
      String value = keyvalues[1];

      if (key.equals(parameter))
        return value;
    }

    return "";
  }

  int enviaComandoPOS(String sIP, int iPorta, String sIdComando, String sValorComando)
  {
    Log.v("CPOS", "enviaComandoPOS: " + sIP + ":" + iPorta);
  
    sDadosComando = sIdComando + "=" + sValorComando;
    try
    {
      Boolean Resultado = new EnviaComando().execute("").get();
    }
    catch (Exception e)
    {
    }

    int res = 0;
    
    Log.v("CPOS", "dados recebidos = " + buffer + " length = " + buffer.length);
    Log.v("CPOS", "dados recebidos [0] = " + buffer[0]);
    Log.v("CPOS", "dados recebidos [1] = " + buffer[1]);
    if ((bChegaramDados) && (buffer.length >= 2))
    {
      if (buffer[0] == 'O' && buffer[1] == 'K')			  							  		
        res = 0;
      else
        res = -1;
    }
    else
      res = -2; // timeout

    Log.v("CPOS", "enviaComandoPOS finaliza: " + sIP + ":" + iPorta);

    if (!sIdComando.equals("FINALIZA"))
    {
      sDadosComando = "FINALIZA=";
      try
      {
        Boolean Resultado = new EnviaComando().execute("").get();
      }
      catch (Exception e)
      {
      }
    }
    
    try
    {
      socket.close();
    }
    catch (Exception e)
    {
    }
    
    bSocketAberto = false;	 				  							  	
    return res;
  }
  
  public String ConverteHexaToAscii(String sHexa)
  {
    StringBuilder output = new StringBuilder();
    for (int i = 0; i < sHexa.length(); i+= 2) {
      String str = sHexa.substring(i, i+2);
      output.append((char) Integer.parseInt(str, 16));
    }
    return output.toString();
  }

  public void comandoPOS(String parameters) {
    Log.v("CPOS", "posValor parametros=" + parameters);
    sIP = ValorParametro(parameters, "IPPOS");
    iPorta = Integer.parseInt(ValorParametro(parameters, "PortaPOS"));
    final String sIdComando = ValorParametro(parameters, "IdComando");
    String sValorComandoHexa = ValorParametro(parameters, "ValorComando");
    final String sValorComando = ConverteHexaToAscii(sValorComandoHexa);

    Thread thread = new Thread()
    {
      @Override
      public void run() {
        final int iResultado;
        iResultado = enviaComandoPOS(sIP, iPorta, sIdComando, sValorComando);

        Log.v("CPOS", "resultado enviaComandoPOS = " + iResultado);

        runOnUiThread(new Runnable() {
          public void run() {
            Intent intent = getIntent();

            if (iResultado == 0)
            {
              Log.v("CPOS", "Vai chamar  setResult 1");
//              ArrayList<String> al = new ArrayList<String>();
              intent.putExtra("Parameters", "{}");
              setResult(Activity.RESULT_OK, intent);
              Log.v("CPOS", "chamou setResult 2");
              finish();
              Log.v("CPOS", "Chamou finish 3");
            }
            else
            {
              Log.v("CPOS", "Vai chamar  setResult 4");
              setResult(Activity.RESULT_CANCELED, intent);
              Log.v("CPOS", "Vai chamar  finish 5");
              finish();
              Log.v("CPOS", "Chamou finish 6");
            }
          }
        });
      }
    };
    thread.start();
  }

  private Runnable ProcessoLeitura = new Runnable() {

    @Override
    public void run() {
      char [] tamanho = new char[4];
      try
      {
/*        
        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while (true)
        {
          if (input.ready())
          {
            input.read(tamanho, 0, 4);
            break;
          }
        }
        int tam = Integer.parseInt(new String(tamanho), 4);
        while (true)
        {
          if (input.ready())
          {
            input.read(buffer, 0, tam);
            bChegaramDados = true;
            break;
          }
        }
*/
        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while(true)
        {
          if(input.ready())
          {
            input.read(buffer,0,2);
            Log.v("CPOS", "Lidos 2 bytes = " + buffer + " length = " + buffer.length);
            bChegaramDados = true;  	            			
            break;
          }
        }		

      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  };

  public class EnviaComando extends AsyncTask<String, Void, Boolean>
  {

    @Override
    protected Boolean doInBackground(String... params)
    {

      try
      {
        bChegaramDados = false;
        if (bSocketAberto == false)
        {
          InetAddress serverAddr = InetAddress.getByName(sIP);
          socket = new Socket(serverAddr, iPorta);
          bSocketAberto = true;
        }
        if (socket != null)
        {
          PrintWriter outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

          // inserir tamanho
          String StrEnvio = String.format("%04d", sDadosComando.length()) + sDadosComando;
          
          Log.v("CPOS", "StrEnvio = " + StrEnvio);
          
          outToServer.print(StrEnvio);
          outToServer.flush();
          // espera resposta
          long start = System.currentTimeMillis();
          long delay = System.currentTimeMillis();

          Thread myThread = new Thread(ProcessoLeitura, "loop");
          myThread.start();

          while (Math.abs(delay - start) < 30000)
          {
            if (bChegaramDados == true)
              break;
            delay = System.currentTimeMillis();
          }

//          socket.close();
//          bSocketAberto = false;
        }

      } catch (UnknownHostException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
      catch (Exception e)
      {
        String sError = e.toString();
      }
      return true;
    }
  };

}

