package oracle.forms.fd;

import java.net.InetAddress;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.html.HTMLEditorKit;
import oracle.forms.handler.IHandler;
import oracle.forms.ui.VBean;
import oracle.forms.properties.ID;
import oracle.forms.ui.CustomEvent;

  /**
   * A Bean to transform the Forms module
   * to a socket server that allow to chat
   * between other Forms sessions
   *
   * @author Francois Degrelle
   * @version 1.0
   * 
   */
   
public class ChatClient extends VBean  implements Runnable 
{
  // variables for Chat
  public final static ID initServer      = ID.registerProperty("INIT_SERVER");        
  public final static ID stopServer      = ID.registerProperty("STOP_SERVER");          
  private static final ID SEND_MSG       = ID.registerProperty("SENDMSG");        
  private static final ID GET_IP         = ID.registerProperty("GET_IP");          
  private static final ID GET_USERNAME   = ID.registerProperty("GET_USERNAME");            
  private static final ID MESSAGEVALUE   = ID.registerProperty("MESSAGEVALUE");     
  // variables for HTML pane
  protected static final ID pSetText     = ID.registerProperty("SET_TEXT");
  protected static final ID pAddText     = ID.registerProperty("ADD_TEXT");
  protected static final ID pGetText     = ID.registerProperty("GET_TEXT");
  
  static Thread              runner ;
  public static boolean      bMsg = false ;
  public static String       sMessage = "" ;
  public static boolean      bOk = false ;
  private boolean            bLog = false ;
  private static IHandler    mHandler;  
  private InetAddress        m_localhost = null;
  private ChatServer         server ; // special class that init the socker server
  protected JTextPane        m_editor;
  protected HTMLEditorKit    m_kit;    

      
  public void init(IHandler handler)
  {
    mHandler = handler;
    super.init(handler);
  }  
  
  public ChatClient()
  {
    // new JTextpane
    m_editor = new JTextPane();
    m_kit = new HTMLEditorKit();
    m_editor.setEditorKit(m_kit);
    m_editor.setEditable(false);
    JScrollPane ps = new JScrollPane(m_editor);
    add(ps);
    ps.setVisible(true);    
  }
  
      // we start the thread here
      private void startThread()
      {
        if (runner == null )
        {
          runner = new Thread(this);
          runner.start();
        }
      }
      
      // we stop the thread here
      private static void stopThread()
      {
        if (runner != null )
        {
          runner = null;
        }
      }    

      // Start the thread
      public void run()
      {
        Thread theThread = Thread.currentThread();   
        while (runner == theThread)
        {
            // let the processor take a deep breath
            try {
                theThread.sleep(1000);
            } catch (InterruptedException e) {;}
            // tell Forms that a message is incoming
            if( bMsg )
            {
              System.out.println("Sendmessage="+sMessage);
              SendMessage(sMessage) ;
              bMsg = false ;
              if( sMessage.equalsIgnoreCase("BYE."))
                stopThread() ;
            }
        }
      }      
  
  /*
   *  Set some properties 
   */
  public boolean setProperty(ID property, Object value)
  {
    // Start the socket server on the given port
    if( property == initServer )
    {
      int iPort = Integer.parseInt((String)value) ;
      server = new ChatServer(iPort);
      server.start();
      startThread() ;
      if( bOk ) SendMessage("[SocketServerOK]") ;
      return true ;
    }
    // Stop the socket server
    else if( property == stopServer )
    {
      if( bOk )
      {
        stopThread() ;
        bOk = false ;
      }
      return true ;
    }
    else if (property == pSetText) // set the user value
    {
      String s = (String)value ;
      m_editor.setText(s);
      return true;
    }        
    else
    {
     return super.setProperty(property, value);
    }
  }  
  
  public Object getProperty(ID pid)
  {
    if(pid == GET_USERNAME)
    {
      return (getUsername());
    }
    else if(pid == GET_IP)
    {
      return(getIPAddress());
    }
    else if (pid == pGetText)
    {
      return "" + m_editor.getText();
    }    
    else
      return(super.getProperty(pid));
  }  

  
  // send message back to Forms
  public void SendMessage( String sMessage )
  {
    try{
      CustomEvent ce = new CustomEvent(mHandler, SEND_MSG);
      mHandler.setProperty( MESSAGEVALUE, sMessage );
      dispatchCustomEvent(ce);  
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }    
  }

  /**
   * Find the localhost InetAddress for the client machine in which this
   * class is currently running.  This method must have been called before
   * the other convenience functions are called since the depend on the
   * value it provides.
   */
  private void findLocalHost()
  {
    if(m_localhost == null)
    {
      try
      {
        Log("obtaining LocalHost info from InetAddress");
        m_localhost = InetAddress.getLocalHost();
      }
      catch(Exception e)
      {
        Log("ERROR obtaining LocalHost info from InetAddress");
        e.printStackTrace();
      }
    }
  }


  /**
   * Obtains the username from the client's JVM System properties with "user.name"
   * @return the client username
   */
  public String getUsername()
  {
     return System.getProperty("user.name");
  }

  /**
   * Obtains the IP address of the local client machine
   *
   * @ return the IP Address or the default message in case of error
   */
  public String getIPAddress()
  {
    findLocalHost();
    if(m_localhost != null)
      return m_localhost.getHostAddress();
    else
      return "IP NOT AVAILABLE";
  }

  public void Log( String sMessage )
  {
    if( bLog ) System.out.println( sMessage ) ;
  }
}
