package oracle.forms.fd;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.util.StringTokenizer;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import oracle.forms.ui.VBean;
import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;

    /**
     * A javabean that read/display/write images
     * 
     * image can be read from file system or database BLOB column
     * image can be written to database BLOB column
     * image can be scaled to fit the display size
     * 
     * use the JDBC driver to connect to the database
     * 
     * @author Francois Degrelle
     * @version 1.2
     *
     */

    public class HandleImage   extends VBean
    {
      public final static ID SETPOS            = ID.registerProperty("SETPOS");   
      public final static ID SETBG             = ID.registerProperty("SETBG");   
      public final static ID SETLOG            = ID.registerProperty("SETLOG");   
      public final static ID CLEAR             = ID.registerProperty("CLEAR");   
      public final static ID GETSIZE           = ID.registerProperty("GETSIZE");           
      public final static ID GETMODIFIER       = ID.registerProperty("GETMODIFIER");           
      public final static ID READIMGBASE       = ID.registerProperty("READIMGBASE");         
      public final static ID READIMGFILE       = ID.registerProperty("READIMGFILE");         
      public final static ID WRITEIMGBASE      = ID.registerProperty("WRITEIMGBASE");               
      public final static ID SCALEIMAGE        = ID.registerProperty("SCALE_IMAGE");               
      public final static ID SETSCROLL         = ID.registerProperty("SETSCROLL");               
      protected static final ID SETCONN        = ID.registerProperty("SETCONN");
      protected static final ID SETUSER        = ID.registerProperty("SETUSER");    
      protected static final ID SETPWD         = ID.registerProperty("SETPWD");          
      protected static final ID SETTABLEINFO   = ID.registerProperty("SETTABLEINFO");
      protected static final ID SETFILECHOOSER = ID.registerProperty("SET_FILECHOOSER_TITLE");
      protected static final ID SETCHOOSERLAF  = ID.registerProperty("SET_FILECHOOSER_LAF");
      protected static final ID GETFILENAME    = ID.registerProperty("GET_FILE_NAME");
      private   String      sFileChooserTitle = "Select an image file" ;
      private   String      sFileStartDir = "" ;
      private   IHandler    m_handler; 
      private   ImagePanel  mp = null ;
      private   JScrollPane jsp = null ;      
      private   Image       imgReal  = null ;
      private   Image       imgShown = null ;
      private   String      sChooserLAF = "SYSTEM" ;
      private   LectureBlob lb = new LectureBlob();
      private   boolean     bLog = false ;
      private   boolean     bImg = false ;
      private   URL         m_codeBase;
      private   File        file_image = null ;
      private   FileInputStream fis = null ;
      private   int         iMageSize = 0 ;
      private   int         iScaleWidth=-1, iScaleHeight=-1 ;
      private   JPanel      jp = new JPanel() ;
      private   Color       colorBackGround = Color.white ;
      private   Border      border, loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);      
     
      public HandleImage()
      {
         super();
      }
       
      public void init(IHandler handler)
      {
        m_handler = handler;
        super.init(handler);
        try
        {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
          SwingUtilities.updateComponentTreeUI(this);
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }             
        // create the panel
        mp = new ImagePanel(this.getWidth(),this.getHeight()) ;
        mp.setVisible(true);
        mp.setBorder(BorderFactory.createEmptyBorder());
        // create the JScrollPane and associate with the panel
        jsp =  new JScrollPane(mp) ;
        jsp.setPreferredSize(new Dimension(this.getWidth(),this.getHeight()));
        jsp.setVisible(true);
        jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
        jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        add(jsp);
      }     
 
      /**----------------------------------*
       *  set the properties of the bean   *
       *-----------------------------------*/
      public boolean setProperty(ID property, Object value)
      {
        //
        // read an image from a file
        //
        if (property == READIMGFILE)  
        {
          String sFileName = value.toString() ;
          imgReal = loadImage( sFileName ) ;
          if(imgReal == null) return false;
          bImg = true ;
          if((iScaleWidth != 0) && (iScaleHeight != 0))
          {
            ImageIcon icon = new ImageIcon(imgReal.getScaledInstance(iScaleWidth, iScaleHeight, Image.SCALE_SMOOTH));
            imgShown = icon.getImage();
            mp.setImage(imgShown) ;
          }
          else
            mp.setImage(imgReal) ;
          return true;
        }
        
        //
        // read an image from the database
        //
        else if (property == READIMGBASE)  
        {        
          try {
            imgReal = lb.Lecture( value.toString() ) ;
            if(imgReal == null) return false;
            bImg = true ;         
            if((iScaleWidth != 0) && (iScaleHeight != 0))
            {
              ImageIcon icon = new ImageIcon(imgReal.getScaledInstance(iScaleWidth, iScaleHeight, Image.SCALE_SMOOTH));
              imgShown = icon.getImage();
              mp.setImage(imgShown) ;
            }
            else 
                mp.setImage(imgReal) ;
          }
          catch (Exception e) {
               System.out.println( "Exception in lb.Lecture() "+e.toString()) ;
               return false ;
          }          
          return true;
        }
        
        //
        // write an image to the database
        //
        else if (property == WRITEIMGBASE)  
        {
         
          try {
          log("Start Ecriture()") ;
          lb.Ecriture( value.toString(), fis, iMageSize ) ;
          log("End Lecture()") ;
          }
          catch (Exception e) {
               System.out.println( e.toString()) ;
          }          
          return true;
        }        

        //
        // init the connect string
        //
        else if (property == SETCONN)
         {
            lb.sConn = (String)value ;
            log("InitConn="+lb.sConn) ;                 
            return true;
         }     

        //
        // init the username
        //
        else if (property == SETUSER)
         {
            lb.sUser = (String)value ;
            log("InitUser="+lb.sUser) ;       
            return true;
         }     

        //
        // init the password
        //
        else if (property == SETPWD)
         {
            lb.sPwd  = (String)value ;
            log("InitPwd="+lb.sPwd) ;       
            return true;
         }     

        //
        // set the background color
        //
        else if (property == SETTABLEINFO) 
        {
          String s = value.toString().trim();
          String sTable="", sCol="", sIdent="" ;
          StringTokenizer st = new StringTokenizer(s,",");
          lb.sTable  = st.nextToken() ;
          lb.sColumn = st.nextToken() ;
          if(st.hasMoreTokens()) lb.sLookup = st.nextToken() ;

          return true;
        }        
        
        //
        // set the position of the image
        //
        else if (property == SETPOS) 
        {
          int iPos = new Integer((String)value).intValue() ;
          return true;
        }
        
        //
        // set the background color
        //
        else if (property == SETBG) 
        {
          String color = value.toString().trim();
          int r=-1, g=-1, b=-1, c=0 ;
          StringTokenizer st = new StringTokenizer(color,",");
          while (st.hasMoreTokens()) {
                   c = new Integer((String)st.nextToken()).intValue()  ;
                   if( (c <0) || (c > 255) ) c = 0 ;
                   if( r == -1 ) r = c ;
                   else if( g == -1 ) g = c ;
                   else if( b == -1 ) b = c ;
                 }
          mp.setBGColor(new Color(r, g, b)) ;
          return true;
        }

        //
        // clear the image
        //
        else if (property == CLEAR) 
        {
          log("Clear imge") ;          
          imgReal = null ;
          imgShown = null ;
          lb.blobImage = null ;
          //mp.revalidate() ;
          mp.setImage(null) ;
          return true;
        }

        //
        // image scaling
        //
        else if (property == SCALEIMAGE)  
        {
          String s   = value.toString();
          String tok = "" ;
          int    i   = 0 ;
          System.out.println("SCALE_IMAGE="+s);
          StringTokenizer st = new StringTokenizer(s,",");
          while(st.hasMoreTokens())
          {
            tok = st.nextToken().toUpperCase() ;
            // width ?
            if(tok.startsWith("WIDTH="))
            {
              tok = tok.substring(6);
              if(tok.equalsIgnoreCase("FIT"))
              {
                System.out.println("jsp Width="+jsp.getSize());
                iScaleWidth = (int)jsp.getSize().getWidth();
              }
              else
              {
                try
                {
                  iScaleWidth = Integer.parseInt(tok);
                  if(iScaleWidth < -1) iScaleWidth = 0 ;
                }
                catch (Exception e) {
                  System.out.println( "SCALE_IMAGE : bad Width integer value provided") ;
                  return false ;
                }
              }
              System.out.println("Scale Width="+iScaleWidth);
            }
            // height ?
            if(tok.startsWith("HEIGHT="))
            {
              tok = tok.substring(7);
              if(tok.equalsIgnoreCase("FIT"))
              {
                iScaleHeight = (int)jsp.getSize().getHeight();
              }              
              else
              {
                try
                {
                  iScaleHeight = Integer.parseInt(tok);
                    if(iScaleHeight < -1) iScaleHeight = 0 ;
                }
                catch (Exception e) {
                  System.out.println( "SCALE_IMAGE : bad Height integer value provided") ;
                  return false ;
                }          
              }
              System.out.println("Scale Height="+iScaleHeight);
            }
          }
          return true;
        }
        
        //
        // set the FileChooser title and starting directory
        //
        else if(property ==SETFILECHOOSER) {
            String s = (String)value ;
            StringTokenizer st = new StringTokenizer(s,",");
            if(st.hasMoreTokens()) sFileChooserTitle = st.nextToken() ;
            if(st.hasMoreTokens()) sFileStartDir = st.nextToken() ;
            return true ;
        }
        
        //
        // set the JFileChooser L&F
        //
        else if(property==SETCHOOSERLAF) {
            sChooserLAF = (String)value ;
            return true ;
        }
        
        //
        // show/hide the scrollbars
        //
        else if (property == SETSCROLL) 
        {
          String s = (String)value ;
          if( s.equalsIgnoreCase("TRUE"))
          {
            jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
            jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
          }
          else 
          {
            jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
            jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
          }            
          return true;
        }        
        
        //
        // set the log flag to output the messages on the console
        //
        else if (property == SETLOG) 
        {
          String s = (String)value ;
          if( s.equalsIgnoreCase("TRUE"))
          {
            bLog= true ;
            lb.bLog = true ;
            log("Lecture.bLog="+lb.bLog) ;
          }
          else 
          {
            bLog = false ;
            lb.bLog = false ;
          }            
          return true;
        }        
        
        else
        {
         return super.setProperty(property, value);
        }
      }

      /**----------------------------------*
       * Get the properties from the bean  *
       *-----------------------------------*/
      public Object getProperty(ID pId) 
      {
        //
        // returns image size
        //
        if( pId == GETSIZE)
        {
          int w=0, h=0 ;
          //return "" + mp.getImageWidth()+","+mp.getImageHeight() ;
          if(imgReal != null)
          {
            ImageIcon icon = new ImageIcon(imgReal);
            w = icon.getIconWidth();
            h = icon.getIconHeight() ;
          }
          return  "" + w + "," + h ;
        }
        //
        // returns selected filename
        //
        else if(pId == GETFILENAME)
        {
          GetImageFileName gifn = new GetImageFileName() ;
          //if(sChooserLAF.equalsIgnoreCase("SYSTEM"))
          gifn.SetLAF(sChooserLAF.toUpperCase());
          return gifn.GetFile(sFileChooserTitle,sFileStartDir) ;
        }
        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 ;
      imageName = p_imageName ;
      fis = null ;
  
      // add    
      try {
      file_image = new File( imageName );
      fis = new FileInputStream( file_image );
      }
      catch( Exception e )
          {
            System.out.println("loadImage:"+e.toString());
          }      
      iMageSize = ( int )file_image.length() ;
      //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)
      {
        imageName = "file:///" + p_imageName ;
        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
          {
            if(imageURL != null)
            {
              img = Toolkit.getDefaultToolkit().getImage(imageURL);
              loadSuccess = true;
              log("Image found in DOCBASE: " + imageURL.toString());
              return img ;
            }
            else
               System.out.println("imageURL == null");
          }
          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)
      {
        System.out.println("Error image " + imageName + " could not be located");
      }
      return img ;
    }
    
  /**----------------------------*
   *  A panel to draw the image  *
   *-----------------------------*/
  public class ImagePanel extends JPanel
  {
    private Image  img = null ;
    private Color  colorBG = null ;
    private int    iImageWidth = 0, iImageHeight = 0 ;
    private int    iInitialWidth = 0, iInitialHeight = 0 ;
    
    public ImagePanel( int iWidth, int iHeight)
    {
      iInitialWidth  = iWidth ;
      iInitialHeight = iHeight ;
      this.setPreferredSize(new Dimension(iInitialWidth,iInitialHeight));
    }
    
    // set the image
    public void setImage( Image p_image )
    {
      img = p_image ;
      if( img != null )
      {
        ImageIcon ii = new ImageIcon(img) ;
        iImageWidth  = ii.getIconWidth() ;
        iImageHeight = ii.getIconHeight() ;    
        // ajust the panel size to the new image size
        this.setPreferredSize(new Dimension(iImageWidth,iImageHeight));
      }
      else
      {
         // restore panel size to its initial values
         this.setPreferredSize(new Dimension(iInitialWidth,iInitialHeight)) ;
         iImageWidth = iImageHeight = 0 ;
      }
      this.revalidate();
    }
    
    // set the background color
    public void setBGColor( Color p_color )
    {
      colorBG = p_color ;
    }
    
    // get the image width
    public int getImageWidth()
    {
      return iImageWidth ;
    }  
    
    // get the image height
    public int getImageHeight()
    {
      return iImageHeight ;
    }    
    
    // draw the image
    protected void paintComponent(Graphics g) {
      if( colorBG != null )
      {
         g.setColor(colorBG);
         g.fillRect(0, 0, this.getWidth(), this.getHeight());
      }
      if( img != null ) g.drawImage(img, 0, 0, this);  
    }  
  }

    
  public void log( String sMessage )
  {
    if( bLog) System.out.println( sMessage ) ;
  }   

    
}     