package oracle.forms.fd;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.StringTokenizer;
import javax.swing.Icon;
import javax.swing.JButton;
import oracle.forms.ui.VButton;
import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import oracle.forms.properties.Property;

    /**
     * A Swing JButton's PJC
     * 
     * the standard Forms button is overloaded
     * by a Swing JButton to allow
     * some nice decoration
     * 
     * need the JRE 1.4 to use Gradient feature
     * 
     * @author Francois Degrelle
     * @version 1.0
     *
     */
     
public class SwingButton extends VButton
{
  private static final ID SETIMAGEON        = ID.registerProperty("SET_IMAGE_ON");
  private static final ID SETIMAGEOFF       = ID.registerProperty("SET_IMAGE_OFF");
  private static final ID SETDEBUG          = ID.registerProperty("SET_DEBUG");
  private static final ID SETBORDERCOLOR    = ID.registerProperty("SET_BORDER_COLOR");
  private static final ID SETTEXTPOS        = ID.registerProperty("SET_TEXT_POSITION");  
  private static final ID SETTEXTCOLOR      = ID.registerProperty("SET_TEXT_COLOR");    
  private static final ID SETSHADOWCOLOR    = ID.registerProperty("SET_SHADOW_COLOR");  
  private static final ID SETGRADIENT       = ID.registerProperty("SET_GRADIENT_COLOR");  
  private static final ID SETGRADIENTDIR    = ID.registerProperty("SET_GRADIENT_DIR");   
  private static final ID SETROUNDED        = ID.registerProperty("SET_ROUNDED"); 
  private static final ID SETIMAGE          = ID.registerProperty("SET_IMAGE");  
  private static final ID SETIMAGEPOS       = ID.registerProperty("SET_IMAGE_POSITION");    
  private final int ON = 1;
  private final int OFF = 0;
  private final String CLASSNAME = this.getDefaultName();
  private final String  JARBUTTONSDIR = "/";
  private final String  JARBUTTONSEXT = ".gif";
  private String  m_imageNameOn;
  private String  m_imageNameOff;
  private IHandler  m_handler;
  private URL m_codeBase;
  private int m_state = OFF;
  private Image[] m_images = { null, null };
  private boolean m_isRollover = false;
  private boolean m_debug = false;
  private   File        file_image = null ;
  private   FileInputStream fis = null ;  
  private   int         iMageSize = 0 ;
  private JButton jb = new JButton();
  private CButton cb ;
  private boolean bFirst = true ;


  public SwingButton()
  {
    super();
    log("Debugging on: Creating Button Instance");
    cb = new CButton("");
    setLeftmost(false);
    setRightmost(false);
  }

  public void init(IHandler handler)
  {
    m_handler = handler;
    m_codeBase = handler.getCodeBase();
    super.init(handler);
    addMouseListener(new LabledIconButtonMouseAdapter());
  }

  public void paint(Graphics p0)
  {
   
    if(bFirst)
    {
       // get the native button info
       cb.setBounds(this.getBounds());
       this.getParent().add(cb);       
       bFirst = false ;
    }
  }

  /*
   * set the needed properties
   */
  public boolean setProperty(ID property, Object value)
  {
    if (property == ID.LABEL)
    {
      log("Setting Label to : " + value.toString());
      String label = value.toString();
      if(label.equalsIgnoreCase("null")) label = null ;
      if(cb != null)
      {
        cb.setText(label);
        cb.invalidate();
      }
      return super.setProperty(property, label);
    }
    else if (property == ID.FOREGROUND)
    {
      log("Setting Foreground to " + value.toString());
      Color c = (Color)value;
      if(cb != null && c != null)
      {
        cb.setFGcolor(c);
        cb.invalidate();
      }
      return super.setProperty(property, c);
    }    
    else if (property == ID.BACKGROUND)
    {
      log("Setting Background to " + value.toString());
      Color c = (Color)value;
      if(cb != null && c != null)
      {
        cb.setBGcolor(c);
        cb.invalidate();
      }
      return super.setProperty(property, c);
    }
    else if (property == ID.FONT)
    {
      log("Setting Font to " + value.toString());
      Font f = (Font)value;
      if(cb != null && f != null)
      {
        cb.setFonte(f);
        cb.invalidate();
      }
      return super.setProperty(property, f);
    }  
    else if (property == ID.LOCATION)
    {
      log("Setting Location to " + value.toString());
      Point p = (Point)value;
      if(cb != null && p != null)
      {
        cb.setLocation(p);
        cb.invalidate();
      }
      return super.setProperty(property, p);
    }            
    // set the debug mode
    else if (property == SETDEBUG)
    {
      if (value.toString().equalsIgnoreCase("true"))
        m_debug = true;
      else
        m_debug = false;

      log("Debugging " + m_debug);
      return true;
    }
    // set the label position
    else if (property == SETTEXTPOS)
    {
      String s = value.toString() ;
      if(s.equalsIgnoreCase("left")) cb.setTextPosition(1);
      else if(s.equalsIgnoreCase("center")) cb.setTextPosition(2);
      else if(s.equalsIgnoreCase("right")) cb.setTextPosition(3);
      log("setProperty - SETTEXTPOS value=" + value.toString());
      cb.invalidate();
      return true;
    }
    // set the gradient colors
    else if (property == SETGRADIENT)
    {
            String sColor = value.toString().trim();
            int r = -1;
            int g = -1;
            int b = -1;
            StringTokenizer st = new StringTokenizer(sColor, ",");
            try
            {
                r = Integer.parseInt(st.nextToken());
                g = Integer.parseInt(st.nextToken());
                b = Integer.parseInt(st.nextToken());
                Color c1 = new Color(r, g, b);
                r = -1;
                g = -1;
                b = -1;
                r = Integer.parseInt(st.nextToken());
                g = Integer.parseInt(st.nextToken());
                b = Integer.parseInt(st.nextToken());
                Color c2 = new Color(r, g, b);
                cb.setGradientcolors(c1, c2);
                cb.invalidate();
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return false;
            }
      log("setProperty - SETGRADIENT value=" + value.toString());
      return true;
    }
    // set the shadow color
    else if (property == SETSHADOWCOLOR)
    {
      log("setProperty - SETSHADOWCOLOR value=" + value.toString());
          String sColor = value.toString().trim();
          int r = -1;
          int g = -1;
          int b = -1;
          StringTokenizer st = new StringTokenizer(sColor, ",");
          try
          {
              r = Integer.parseInt(st.nextToken());
              g = Integer.parseInt(st.nextToken());
              b = Integer.parseInt(st.nextToken());
              Color c1 = new Color(r, g, b);
              cb.setShadowcolor(c1);
              cb.invalidate();
          }
          catch(Exception e)
          {
              e.printStackTrace();
              return false;
          }
      return true;
    }    
    // set the border color
    else if (property == SETBORDERCOLOR)
    {
      log("setProperty - SETBORDERCOLOR value=" + value.toString());
          String sColor = value.toString().trim();
          int r = -1;
          int g = -1;
          int b = -1;
          StringTokenizer st = new StringTokenizer(sColor, ",");
          try
          {
              r = Integer.parseInt(st.nextToken());
              g = Integer.parseInt(st.nextToken());
              b = Integer.parseInt(st.nextToken());
              Color c1 = new Color(r, g, b);
              cb.setBordercolor(c1);
              cb.invalidate();
          }
          catch(Exception e)
          {
              e.printStackTrace();
              return false;
          }
      return true;
    }    
    // read an image from a file
    else if (property == SETIMAGE)  
        {
          String s = value.toString() ;
          String sPos = null ;
          Image img = null ;
          log("setProperty - SETIMAGE value=" + s);
          String sFileName = s ;
          int    iPos = s.indexOf(",");
          if(iPos > -1)
          {
            sFileName = s.substring(0,iPos) ;
            sPos = (s.substring(iPos+1));
            System.out.println("filename="+sFileName+" position="+sPos);            
          }
          if(! sFileName.equalsIgnoreCase("null")) img = loadImage( sFileName ) ;
          cb.setBTImage(img) ;
          if(sPos != null) cb.setImagePosition(sPos.toUpperCase());
          cb.invalidate();
          return true;
    }
    // read an image from a file
    else if (property == SETIMAGEON)  
        {
          String sFileName = value.toString() ;
          Image img = null ;
          log("setProperty - SETIMAGEON value=" + sFileName);
          img = loadImage( sFileName ) ;
          cb.setImageON(img) ;
          cb.invalidate();
          return true;
    }    
    // set the image position
    else if (property == SETIMAGEPOS)  
        {
          String s = value.toString() ;
          log("setProperty - SETIMAGEPOS value=" + s);
          cb.setImagePosition(s);
          cb.invalidate();
          return true;
    }
    // set the rounded parameters
    else if (property == SETROUNDED)  
        {
          String s = value.toString() ;
          int iW = 20, iH = 20 ;
          log("setProperty - SETROUNDED value=" + s);
          int    iPos = s.indexOf(",");
          if(iPos > -1)
          {
            iW = Integer.parseInt(s.substring(0,iPos)) ;
            iH = Integer.parseInt(s.substring(iPos+1));
            cb.setRounded(iW,iH) ;
            cb.invalidate();
          }
          return true;
    }    
    // set the gradient direction
    else if (property == SETGRADIENTDIR)  
        {
          int g = Integer.parseInt(value.toString()) ;
          if(g>0 && g<5)
          {
            log("setProperty - SETGRADIENTDIR value=" + g);
            cb.setDirection(g) ;
            cb.invalidate();
          }
          return true;
    }
    else
    {
     System.out.println(property+":"+value);
     return super.setProperty(property, value);
    }
  }

  /**
   * Implementation of IView interface which returns the value of a requested property
   *
   * @param pid the property id that represents the property to be set
   * @return the value of the property id
   * @see oracle.forms.ui.IView
   */
  /*
  public Object getProperty(ID pid)
  {
    if ( pid == IMAGE_NAME_OFF )
    {
      return m_imageNameOff;
    }
    else if ( pid == IMAGE_NAME_ON )
    {
      return m_imageNameOn;
    }
    else
      return super.getProperty(pid);
  }
  */


    /*
     *  Load an image from JAR file, Client machine or Internet URL 
     */
    private Image loadImage(String p_imageName)
    {
      URL imageURL = null;
      boolean loadSuccess = false;
      Image img = null ;
      String imageName = p_imageName ;
      
      try {
        file_image = new File( imageName );
        fis = new FileInputStream( file_image );
      }
      catch( FileNotFoundException e2 )
          {
            e2.printStackTrace();
          }                
      catch( Exception e )
          {
            e.printStackTrace();
          }      
          
      iMageSize = ( int )file_image.length() ;
      imageName = "file:///" + p_imageName ;
      //JAR
      log("Searching JAR for " + imageName);
      imageURL = getClass().getResource(imageName);
      if (imageURL != null)
      {
        log("URL: " + imageURL.toString());
        try
        {
          img = Toolkit.getDefaultToolkit().getImage(imageURL);
          loadSuccess = true;
          log("Image found in JAR: " + imageURL.toString());
          return img ;
        }
        catch (Exception ilex)
        {
          log("Error loading image from JAR: " + ilex.toString());
        }
      }
      else
      {
        log("Unable to find " + imageName + " in JAR");
      }

      //DOCBASE
      if (loadSuccess == false)
      {
        log("Searching docbase for " + p_imageName);
        try
        {
          if(p_imageName.toLowerCase().startsWith("http://")||p_imageName.toLowerCase().startsWith("https://"))
          {
            log("trying to read:"+p_imageName);
            imageURL = new URL(p_imageName);
          }
          else if(imageName.toLowerCase().startsWith("file:"))
          {
            imageURL = new URL(imageName);
          }
          else
          {
            imageURL = new URL(m_codeBase.getProtocol() + "://" +m_codeBase.getHost() + ":" + m_codeBase.getPort() + imageName);
          }
          log("Constructed URL: " + imageURL.toString());
          try
          {
            img = createImage((java.awt.image.ImageProducer)imageURL.getContent());
            loadSuccess = true;
            log("Image found in DOCBASE: " + imageURL.toString());
            return img ;
          }
          catch (Exception ilex)
          {
            log("Error reading image - " + ilex.toString());
          }
        }
        catch (java.net.MalformedURLException urlex)
        {
          log("Error creating URL - " + urlex.toString());
        }
      }

      //CODEBASE
      if (loadSuccess == false)
      {
        log("Searching codebase for " + imageName);
        try
        {
          imageURL = new URL(m_codeBase, imageName);
          log("Constructed URL: " + imageURL.toString());
          try
          {
            img = createImage((java.awt.image.ImageProducer)imageURL.getContent());
            loadSuccess = true;
            log("Image found in CODEBASE: " + imageURL.toString());
            return img ;
          }
          catch (Exception ilex)
          {
                  log("Error reading image - " + ilex.toString());
          }
        }
        catch (java.net.MalformedURLException urlex)
        {
          log("Error creating URL - " + urlex.toString());
        }
      }

      if (loadSuccess == false)
      {
        log("Error image " + imageName + " could not be located");
      }
      return img ;
    }



 
  /**
   * Utility function to print out a debug message to the Java Console
   * @param msg string to display, this will be prefixed with the classname of the PJC
   */
  public void log(String msg)
  {
    if(m_debug)
        System.out.println(CLASSNAME + ": " + msg);
  }

  /**
   * Private class to handle user mouse actions and to switch images when the
   * user moves the mouse into and out of the button object.
   */
  class LabledIconButtonMouseAdapter extends MouseAdapter
  {
    /**
     * User moved the mouse over the button, swap to the on image.
     */
    public void mouseEntered(MouseEvent me)
    {
      log("mouseEntered");
      cb.mouseON();
    }

    /**
     * User moved the mouse out of the button, swap to the off image.
     */
    public void mouseExited(MouseEvent me)
    {
      log("mouseExited");
      cb.mouseOFF();
    }
  }
}