package oracle.forms.fd;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.SwingUtilities;
import oracle.forms.engine.Main;
import oracle.forms.ui.CustomEvent;
import oracle.forms.ui.VBean;
import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import javax.swing.UIManager;


    /**
     * A Java Bean that use an
     * Auto Completion ComboBox
     * 
     * @author Francois Degrelle (wrapper)
     * @author unknown creator (Auto Completion stuff)
     * @version 1.2
     *
     * Add the double list feature
     * (code + value)
     * Add null values 
     */

    public class ComboBoxCompletion extends VBean implements FocusListener
    {

      public final static ID INIT              = ID.registerProperty("INIT");   
      public final static ID INIT_NULL         = ID.registerProperty("INIT_NULL");   
      public final static ID SETINDEX          = ID.registerProperty("SELECT_INDEX");   
      public final static ID SETCODE           = ID.registerProperty("SELECT_CODE");
      public final static ID SETVALUE          = ID.registerProperty("SELECT_VALUE");      
      public final static ID GETINDEX          = ID.registerProperty("GET_INDEX");   
      public final static ID GETVALUE          = ID.registerProperty("GET_VALUE");   
      public final static ID SET_ENABLED       = ID.registerProperty("SET_ENABLED");   
      public final static ID SET_VISIBLE       = ID.registerProperty("SET_VISIBLE");   
      public final static ID SET_FONT          = ID.registerProperty("SET_FONT");         
      public final static ID INIT_TWIN         = ID.registerProperty("INIT_TWIN");         
      public final static ID INIT_TWIN_NULL    = ID.registerProperty("INIT_TWIN_NULL");         
      public final static ID SEL_CHANGED       = ID.registerProperty("SELECTION_CHANGED");         
      public final static ID SELECTION_INDEX   = ID.registerProperty("SELECTION_INDEX");
      public final static ID SELECTION_CODE    = ID.registerProperty("SELECTION_CODE");
      public final static ID SELECTION_VALUE   = ID.registerProperty("SELECTION_VALUE"); 
      
      public final static ID KEYTYPED          = ID.registerProperty("KEY_PRESSED");   
      public final static ID KEYCODE           = ID.registerProperty("KEY_CODE");   
      public final static ID KEYCHAR           = ID.registerProperty("KEY_CHAR");   
      public final static ID KEYMOD            = ID.registerProperty("KEY_MODIFIER");        
      
      private   CBAutoCompletion AC = null;
      private   JComboBox   comboBox ;
      private   Vector      v,v2 ;
      public    IHandler    m_handler; 
      private   KeyListener kl ;     
      private   Main        formsMain = null;
      private   boolean     bLog = false ;
      
      
      public ComboBoxCompletion()
      {
         super();
        try{
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
          SwingUtilities.updateComponentTreeUI(this);
        }
        catch(Exception e) {}        
      }
       
      public void init(IHandler handler)
      {
        m_handler = handler;
        super.init(handler);
        formsMain  =  (Main) handler.getApplet();
        addFocusListener(this);
      }     
  
 
      /**----------------------------------*
       *  set the properties of the bean   *
       *-----------------------------------*/
      public boolean setProperty(ID property, Object value)
      {
        log(property + ":" + value);
        //
        // set single value list
        //
        if(property == INIT || property == INIT_NULL)
        {
          v = new Vector();
          String s = value.toString() ;
          StringTokenizer st ;
          st = new StringTokenizer(s,",");
          if(property == INIT_NULL) v.add("");
          while (st.hasMoreTokens()) {
              v.add(st.nextToken());
          } 
          if(comboBox != null) comboBox.removeKeyListener(kl);
          comboBox = new JComboBox(v);
          comboBox.setEditable(true);
          comboBox.addFocusListener(this);
          AC = new CBAutoCompletion(comboBox);
          AC.CBC = this;
          this.add(comboBox);                    
          return true ;
        }        
      //
      // set double value list
      // (code + value)
      //
      if(property == INIT_TWIN || property == INIT_TWIN_NULL)
      {
        v = new Vector();
        v2 = new Vector();
        String s = value.toString() ;
        StringTokenizer st ;
        st = new StringTokenizer(s,",");
        if(property == INIT_TWIN_NULL)
        {
          v.add("");
          v2.add("");
        }  
        while (st.hasMoreTokens()) {
            v.add(st.nextToken());  // code
            v2.add(st.nextToken()); // value
        }    
        if(comboBox != null) comboBox.removeKeyListener(kl);
        comboBox = new JComboBox(v2);
        comboBox.setEditable(true);
        comboBox.addFocusListener(this);
        AC = new CBAutoCompletion(comboBox);
        AC.CBC = this;
        this.add(comboBox);                    
        return true ;
      }        

        //
        // set the starting index
        //
        else if(property == SETINDEX)
        {
          try{
            int i = Integer.parseInt(value.toString());
            if(comboBox != null && (i > 0))
            {
              comboBox.setSelectedIndex(i-1);
            }
          }
          catch (Exception e) {return false ;}
          return true ;
        }        

        //
        // set the starting index by code
        //
        else if(property == SETCODE)
        {
            String s = value.toString() ;
            for(int i=0; i< v.size(); i++)
            {
              if(v.get(i).equals(s))
              {
                comboBox.setSelectedIndex(i);
                return true;
              }  
            }
          comboBox.setSelectedIndex(0);
          return true ;
        }        

        //
        // set the starting index by value
        //
        else if(property == SETVALUE)
        {
            if(v == null) return false ;
            String s = value.toString() ;
            for(int i=0; i< v2.size(); i++)
            {
              if(v2.get(i).equals(s))
              {
                comboBox.setSelectedIndex(i);
                return true;
              }  
            }
          comboBox.setSelectedIndex(0);
          return true ;
        }        
        
        //
        // enable/disable
        //
        else if(property == SET_ENABLED)
        {
           String s  = value.toString() ;
           if(s.equalsIgnoreCase("true")) comboBox.setEnabled(true);
           else if(s.equalsIgnoreCase("false")) comboBox.setEnabled(false);
           return true ;
        }        
        
        //
        // show/hide
        //
        else if(property == SET_VISIBLE)
        {
           String s  = value.toString() ;
           if(s.equalsIgnoreCase("true"))       {comboBox.setVisible(true);this.setVisible(true);}
           else if(s.equalsIgnoreCase("false")) {comboBox.setVisible(false);this.setVisible(false);}
           return true ;
        }        
       //
       // set the font
       //
       else if (property == SET_FONT) 
       {
         String s = value.toString() ;
         String sFont="", sWeight="" ;
         int iWeight = Font.PLAIN ;
         int iSize = 8 ;
         Font f = null;
         StringTokenizer st = new StringTokenizer(s,",");
         if(st.hasMoreTokens()) sFont = st.nextToken() ;
         if(st.hasMoreTokens())
         {
           sWeight = st.nextToken() ;
           if(sWeight.equalsIgnoreCase("B")) iWeight = Font.BOLD ;
           else if(sWeight.equalsIgnoreCase("I")) iWeight = Font.ITALIC ;
           else if(sWeight.equalsIgnoreCase("BI")) iWeight = Font.BOLD + Font.ITALIC ;
         }  
         try{
           if(st.hasMoreTokens()) iSize   = Integer.parseInt(st.nextToken()) ;
         }
         catch (Exception ex) {System.out.println("SetFont:incorrect size");return false;}
         try
         {
           f = new Font(sFont,iWeight,iSize) ;
           comboBox.setFont(f);
         }
         catch (Exception ex) {System.out.println("SetFont:unable to set font");return false;}
         return true ;
       }        
        else
        {
         return super.setProperty(property, value);
        }
      }

   /*-----------------------*
    *  Get the properties
    *-----------------------*/
    public Object getProperty(ID pId) 
    {
      
      //
      // get the current index
      //
      if (pId == GETINDEX)
      {
        int iIndex = comboBox.getSelectedIndex() - 1 ; 
        return "" + iIndex ;
      }
      //
      // get the current value
      //
      if (pId == GETVALUE)
      {
        return "" + comboBox.getSelectedItem() ;
      }
      else
      {
        return super.getProperty(pId);
      }
    }
  
   
  /*--------------------------------------
   *  send the special keys back to Forms
   *-------------------------------------*/
  public  void setKeyPressed(java.awt.event.KeyEvent e)
  {
      try
         {           
           CustomEvent ce = new CustomEvent(m_handler,KEYTYPED);           
           m_handler.setProperty(KEYCODE, ""+e.getKeyCode());
           m_handler.setProperty(KEYCHAR, ""+e.getKeyChar());
           m_handler.setProperty(KEYMOD, KeyEvent.getKeyModifiersText(e.getModifiers()));           
           dispatchCustomEvent(ce);
           
           m_handler.setProperty(KEY_EVENT, e);           
         }
      catch ( Exception ex ){ System.out.println("Unable to send key to Forms");}                        
  }
  
    public void dispatchanevent (int iIndex, String sValue)
    { 
     // this is the method that will dispatch the customEvent to forms
     try{
         CustomEvent ce = new CustomEvent(m_handler,SEL_CHANGED);
         m_handler.setProperty( SELECTION_INDEX, ""+iIndex);
         m_handler.setProperty( SELECTION_CODE, (String)v.get(iIndex-1));
         m_handler.setProperty( SELECTION_VALUE, sValue);
         dispatchCustomEvent(ce);
        }
     catch (Exception e) 
           {System.out.println("DispatchingEvent -> exception while dispatching: " + e);
           }
    }


  /*----------------------------------------*
   *  Make a color from a RGB string
   *  Color c = makeColor( "r128g25b100" ); 
   *----------------------------------------*/
  public static Color makeColor(String s)
  {
    int r=-1, g=-1, b=-1 ;
    String sR = "255", sG = "255", sB = "255" ;
    int iR=255, iG=255, iB=255 ;
    Color c = Color.white ;
    r = s.indexOf("r") ;
    g = s.indexOf("g") ;
    b = s.indexOf("b") ;
    if( r>-1 && g>-1 && b>-1 )
    {
      iR = Integer.parseInt(s.substring(r+1,g)) ;
      iG = Integer.parseInt(s.substring(g+1,b)) ;
      iB = Integer.parseInt(s.substring(b+1)) ;
      try
      {
        c = new Color(iR,iG,iB) ;
      }
      catch( Exception e) {} ;
    }
    return c ;
  }

  public void log( String sMessage )
  {
    if( bLog) System.out.println( sMessage ) ;
  }   

    public void focusGained(FocusEvent e)
     {
         if (e.getComponent() == this)
         {
             comboBox.requestFocus();
         }
    
         try
         {
             m_handler.setProperty(FOCUS_EVENT, e);
         }
         catch ( Exception ex ){}
     }
    
    
     public void focusLost(FocusEvent e)
     {
     }  

}     
