package oracle.forms.fd;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import javax.swing.JComponent;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import oracle.forms.handler.IHandler;
import oracle.forms.ui.*;
import oracle.forms.properties.ID;

  /**
   * A bean to handle frames at runtime
   * it can handle as many frames as needed
   *
   * @author Francois Degrelle
   * @version 2.0
   */

public class frame extends VBean
{
  protected static final ID pSetFrame            = ID.registerProperty("SET_FRAME");
  protected static final ID pSetFrameText        = ID.registerProperty("SET_FRAME_TEXT");  
  protected static final ID pSetFrameTextAlign   = ID.registerProperty("SET_FRAME_TEXT_ALIGNMENT");  
  protected static final ID pSetFrameTextOpaque  = ID.registerProperty("SET_FRAME_TEXT_OPAQUE");  
  protected static final ID pSetFrameFont        = ID.registerProperty("SET_FRAME_FONT");  
  protected static final ID pSetFrameBackground  = ID.registerProperty("SET_FRAME_BACKGROUND");  
  protected static final ID pSetFrameColors      = ID.registerProperty("SET_FRAME_COLORS");  
  protected static final ID pSetFrameGradOrient  = ID.registerProperty("SET_FRAME_GRADIENT_ORIENTATION");  
  protected static final ID pSetFrameRounded     = ID.registerProperty("SET_FRAME_ROUND_BORDER");   
  protected static final ID pSetBounds           = ID.registerProperty("SET_FRAME_BOUNDS");  
  protected static final ID setFrameHCycle       = ID.registerProperty("SET_FRAME_HCYCLE");  
  protected static final ID setFrameVCycle       = ID.registerProperty("SET_FRAME_VCYCLE");    
  protected static final ID pSetFrameTitleColor  = ID.registerProperty("SET_FRAME_TITLE_COLOR");  
  protected static final ID pShowFrame           = ID.registerProperty("SHOW_FRAME");
  protected static final ID pHideFrame           = ID.registerProperty("HIDE_FRAME");
  protected static final ID pRemoveFrame         = ID.registerProperty("REMOVE_FRAME");  
  protected static final ID pRemoveAllFrames     = ID.registerProperty("REMOVE_ALL_FRAMES");  
  protected static final ID pPrintHashMap        = ID.registerProperty("PRINT_FRAME_MAP");   
  private   IHandler      m_handler;  
  private   JComponent    panel ;
  
  // gradient positions
  private static int   LeftToRight   = 1 ;
  private static int   RightToLeft   = 2 ;
  private static int   UpToDown      = 3 ;
  private static int   DownToUp      = 4 ;
  private int     igrDir             = LeftToRight ;
  private Color   cFrameColor        = Color.gray ;
  private Color   cFrameShadow       = Color.lightGray ;
  private Color   cFrameTitleFore    = Color.black ;
  private Color   cFrameTitleBack    = null ;
  private Color   cFrameGradient1    = null ;
  private Color   cFrameGradient2    = null ;
  private String  sFrameTitle        = null ;
  private String  sFrameAligment     = "C" ;
  private int     iFrameWidth        = 2 ;
  private int     iWFrame            = 0 ;
  private int     iHFrame            = 0 ;
  private boolean bRoundedFrame      = false ;
  private boolean bFrameTitleOpaque  = false ;
  private int     iFrameHcycle       = 0 ;
  private int     iFrameVcycle       = 0 ;
  private Font    fFrameFont         = new Font("Verdana", Font.BOLD,14);
  private static String  sName       = "" ;
  private static HashMap hFrames     = new HashMap() ;
  private oracle.forms.ui.VBean VB   = null ;
    
  public void init(IHandler handler)
   {
     super.init(handler);   
     m_handler = handler;
  }
  
  /**
   * Constructor 
   */
  public frame()
  {
    super();
    VB = this ;
  } 


  /********************************************
   *        properties than can be set        *
   ********************************************/
  public boolean setProperty(ID pId, Object pValue)
  {
    /*------------------------------*
     * Set the frame type and title *
     *------------------------------*/
    if (pId == pSetFrame)
    {

      Border br1 = new FrameBorder ( ) ;
      panel = new myPanel(); 
      
      int iNum = 0;
      String sTitle="", sFont="", sJustif="", string, sWeight = "", sPos="", sPosition="T" ;
      int iFontSize = 10, iWeight=Font.PLAIN, iBorderWidth, iWidth=2 ;
      string = pValue.toString();
      StringTokenizer st = new StringTokenizer(string,",");
      sName     = st.nextToken() ;     // frame name
       panel.setName(sName);
      // create frame object
      objFrame of = new objFrame(sName, panel);
      try{
         iWidth = Integer.parseInt(st.nextToken()) ;
         iFrameWidth = iWidth ;
         of.SetFrameWidth(iWidth);
      }
      catch (Exception e) {}
      
      panel.setBorder(br1);
      panel.setOpaque(false);
      
      if (st.hasMoreTokens())
        sTitle     = st.nextToken() ;  // frame Title
      if (st.hasMoreTokens())
        sFont      = st.nextToken() ;  // frame Font
      if (st.hasMoreTokens())
        iFontSize  = Integer.parseInt(st.nextToken()) ;  // frame Font size      
      if (st.hasMoreTokens())
        {
          sWeight = st.nextToken() ;
          if( sWeight.equalsIgnoreCase("N")) iWeight = Font.PLAIN ;
          else 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 ;
        }
      
      // frame position
      if (st.hasMoreTokens())
      {
         sPos = st.nextToken() ;
         if( sPos.equalsIgnoreCase("left") )        sPosition = "L";
         else if( sPos.equalsIgnoreCase("right") )  sPosition = "R";
         else if( sPos.equalsIgnoreCase("top") )    sPosition = "T";
         else if( sPos.equalsIgnoreCase("bottom") ) sPosition = "B";
      } else return false ;      
        
      if (st.hasMoreTokens())
        sJustif    = st.nextToken() ; // frame Justification

      if( sFont != null ) 
      { 
         try{
           Font fFont = new Font(sFont, iWeight, iFontSize) ; 
           fFrameFont = fFont ;
         }
         catch (Exception e) {};
      }

      // frame alignment
      if ( sJustif != null )
      {
        if( sJustif.equalsIgnoreCase("left") )   sFrameAligment = "L";
        if( sJustif.equalsIgnoreCase("right") )  sFrameAligment = "R";
        if( sJustif.equalsIgnoreCase("center") ) sFrameAligment = "C";
      }

      if(sTitle != null) of.setFrameTitle(sTitle);
      if(fFrameFont != null) of.setFrameFont(fFrameFont);
      if(sJustif != null) of.setFrameTextAlign(sPosition,sFrameAligment);

      // add object to hash map
      hFrames.put(sName,of);
      this.getParent().add(panel) ;            
      return true;
    } 
    
    /*-------------------*
     *  title alignment  *
     *-------------------*/
    else if (pId == pSetFrameTextAlign)
    { 
      String s = pValue.toString();
      String sPos="T", sAlign="L" ;
      StringTokenizer st = new StringTokenizer(s,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;
      if (st.hasMoreTokens())
      {
        sPos = st.nextToken() ;
        if( sPos.equalsIgnoreCase("left") )        sPos = "L";
        else if( sPos.equalsIgnoreCase("right") )  sPos = "R";
        else if( sPos.equalsIgnoreCase("top") )    sPos = "T";
        else if( sPos.equalsIgnoreCase("bottom") ) sPos = "B";
      } else return false ;      
      if (st.hasMoreTokens())
      {
        sAlign = st.nextToken() ;
        if( sAlign.equalsIgnoreCase("left") )        sFrameAligment = "L";
        else if( sAlign.equalsIgnoreCase("right") )  sFrameAligment = "R";
        else if( sAlign.equalsIgnoreCase("center") ) sFrameAligment = "C";
        else return false ;
        objFrame of = (objFrame)hFrames.get(sName) ;
        if(of != null) 
        {
          of.setFrameTextAlign(sPos, sFrameAligment);
          hFrames.put(sName,of);
          of.panel.repaint();
        }
      }
      return true ;
    }
    
    /*------------------------------*
     * Set the frame type and title *
     *------------------------------*/
    else if (pId == pSetFrameFont)
    {
      int iNum = 0;
      String string, sFont="", sWeight = "" ;
      int iFontSize = 10, iWeight=Font.PLAIN ;
      string = pValue.toString();
      StringTokenizer st = new StringTokenizer(string,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;      
      if (st.hasMoreTokens())
        sFont      = st.nextToken() ;  // frame Font
      else return false ;
      if (st.hasMoreTokens())
        iFontSize  = Integer.parseInt(st.nextToken()) ;  // frame Font size      
      if (st.hasMoreTokens())
        {
          sWeight = st.nextToken() ;
          if( sWeight.equalsIgnoreCase("N")) iWeight = Font.PLAIN ;
          if( sWeight.equalsIgnoreCase("B")) iWeight = Font.BOLD ;
          if( sWeight.equalsIgnoreCase("I")) iWeight = Font.ITALIC ;
          if( sWeight.equalsIgnoreCase("BI")) iWeight = Font.BOLD | Font.ITALIC ;
        }
      try{
        Font fFont = new Font(sFont, iWeight, iFontSize) ; 
        fFrameFont = fFont ;
      }
      catch (Exception e) {};
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of != null) 
      {
        of.setFrameFont(fFrameFont);
        hFrames.put(sName,of);
        of.panel.repaint();
      }      
      return true;
    }     
    
    /*-----------------------------*
     *  set the frame title color  *
     *-----------------------------*/
    else if (pId == pSetFrameTitleColor)
    {
      String s = pValue.toString();
      String sColor="" ;
      StringTokenizer st = new StringTokenizer(s,",");
      cFrameTitleBack = null ;
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;
      if (st.hasMoreTokens()) sColor = st.nextToken() ;
      else return false ;
      cFrameTitleFore = makeColor(sColor) ;
      if (st.hasMoreTokens())
      {
        sColor = st.nextToken() ;      
        cFrameTitleBack = makeColor(sColor) ;
      }
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of != null) 
      {
        of.setFrameTitleColors(cFrameTitleFore,cFrameTitleBack);
        hFrames.put(sName,of);
        of.panel.repaint();
      }            
      return true;
    }

    /*----------------------------------*
     *  set the frame background color  *
     *----------------------------------*/
    else if (pId == pSetFrameBackground)
    {
      String s = pValue.toString().trim();
      String sCol1 =null, sCol2= null, sTransp="" ;
      float f = .5f ;
      StringTokenizer st = new StringTokenizer(s,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;      
      // first gradient color
      if (st.hasMoreTokens())
      {
        sCol1 = st.nextToken() ;
        cFrameGradient1 = makeColor(sCol1) ;
      }
      else return false ;
      // second gradient color
      if (st.hasMoreTokens()) 
      {
        sCol2 = st.nextToken() ;
        if(! sCol2.equalsIgnoreCase("-")) cFrameGradient2 = makeColor(sCol2) ;
        else cFrameGradient2 = null ;
      }
      else
          cFrameGradient2 = null ;
      // transparency
      if (st.hasMoreTokens()) 
      {
         try{
           f = Float.parseFloat(st.nextToken());
         }
         catch (Exception e) {}
      }      
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of != null) 
      {
        of.setFrameBackground(cFrameGradient1,cFrameGradient2,f);
        hFrames.put(sName,of);
        of.panel.repaint();
      }            
      return true;
    }         
    
   /*------------------------*
    *  set the frame colors  *
    *------------------------*/
   else if (pId == pSetFrameColors)
   {
     cFrameShadow = null ;
     String s = pValue.toString().trim();
     String sCol1 =null, sCol2= null ;
     StringTokenizer st = new StringTokenizer(s,",");
     if (st.hasMoreTokens()) sName = st.nextToken() ;
     else return false ;      
     if (st.hasMoreTokens())
     {
       sCol1 = st.nextToken() ;
       cFrameColor = makeColor(sCol1) ;
     }
     else return false ;
     if (st.hasMoreTokens()) 
     {
       sCol2 = st.nextToken() ;
       cFrameShadow = makeColor(sCol2) ;
     }
     else
         cFrameShadow = null ;
     objFrame of = (objFrame)hFrames.get(sName) ;
     if(of != null) 
     {
       of.setFrameColors(cFrameColor,cFrameShadow);
       hFrames.put(sName,of);
       of.panel.repaint();
     }
     return true;
   }         
      
    /*------------------*
     *  set the bounds  *
     *------------------*/
    else if (pId == pSetBounds)
    {
      int x = 0, y = 0, w = 0, h = 0;
      String sLabel, s ;
      s = pValue.toString();
      StringTokenizer st = new StringTokenizer(s,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;      
      if (st.hasMoreTokens()) x = Integer.parseInt(st.nextToken()) ; else return false;
      if (st.hasMoreTokens()) y = Integer.parseInt(st.nextToken()) ; else return false;
      if (st.hasMoreTokens()) w = Integer.parseInt(st.nextToken()) ; else return false;
      if (st.hasMoreTokens()) h = Integer.parseInt(st.nextToken()) ; else return false;
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of != null) 
      {
        of.setBounds(x,y,w,h);
        of.iWFrame = w ;
        of.iHFrame = h ;
        hFrames.put(sName,of);
        of.panel.repaint();
      }      
      return true;
    } 
    
    /*----------------------*
     *  set the title text  *
     *----------------------*/
    else if (pId == pSetFrameText) 
    {
      String title="", sJustif=null, sPos="T", s = pValue.toString() ;
      StringTokenizer st = new StringTokenizer(s,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;      
      if (st.hasMoreTokens()) title  = st.nextToken() ; else return false ;
      // frame position
      if (st.hasMoreTokens())
      {
        sPos = st.nextToken() ;
        if( sPos.equalsIgnoreCase("left") )        sPos = "L";
        else if( sPos.equalsIgnoreCase("right") )  sPos = "R";
        else if( sPos.equalsIgnoreCase("top") )    sPos = "T";
        else if( sPos.equalsIgnoreCase("bottom") ) sPos = "B";
      }  
      // frame alignment
      if (st.hasMoreTokens())
      {
        sJustif    = st.nextToken() ;   // title Justification      
        if( sJustif.equalsIgnoreCase("left") )   sFrameAligment = "L";
        else if( sJustif.equalsIgnoreCase("right") )  sFrameAligment = "R";
        else if( sJustif.equalsIgnoreCase("center") ) sFrameAligment = "C";
        else sJustif = null ;
      }
      sFrameTitle = title ;
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of != null) 
      {
        of.setFrameTitle(sFrameTitle);
        if(sJustif != null) of.setFrameTextAlign(sPos,sFrameAligment);
        of.panel.repaint();
        hFrames.put(sName,of);
        of.panel.repaint();
      }            
      return true;
    }    
    
    /*------------------------*
     *  Gradient orientation  *
     *------------------------*/
     else if (pId == pSetFrameGradOrient)
     { 
       String s = pValue.toString(), sDir=null; 
       StringTokenizer st = new StringTokenizer(s,",");
       if (st.hasMoreTokens()) sName = st.nextToken() ;
       else return false ;   
       if (st.hasMoreTokens())
       {
         sDir = st.nextToken() ;
         if(sDir.equalsIgnoreCase("LeftToRight")) igrDir = LeftToRight ;
         else if(sDir.equalsIgnoreCase("RightToLeft")) igrDir = RightToLeft ;
         else if(sDir.equalsIgnoreCase("UpToDown")) igrDir = UpToDown ;
         else if(sDir.equalsIgnoreCase("DownToUp")) igrDir = DownToUp ;
         else return false ;
         objFrame of = (objFrame)hFrames.get(sName) ;
         if(of != null) 
         {
           of.SetFrameGradOrient(igrDir);
           hFrames.put(sName,of);
           of.panel.repaint();
         }                     
       }
       return true ;
     }
     
    /*--------------------------*
     * set the horizontal cycle
     *--------------------------*/
    else if (pId == setFrameHCycle) 
    {
      String s = pValue.toString(); 
      String sVal="";
      StringTokenizer st = new StringTokenizer(s,",");
      if (st.hasMoreTokens()) sName = st.nextToken() ;
      else return false ;
      objFrame of = (objFrame)hFrames.get(sName) ;
      if(of == null) return false ;
      if (st.hasMoreTokens())
      {
          sVal = st.nextToken() ;
          int i = 0 ;
          if(sVal.startsWith("/"))
          {
            i = Integer.parseInt(sVal.substring(1));
            iFrameHcycle = of.iHFrame / i ;
          }
          else
          {
            i = Integer.parseInt(sVal);
            iFrameHcycle = i ;
          }

          of.setFrameHCycle(iFrameHcycle);
          hFrames.put(sName,of);
          of.panel.repaint();
      }
      return true ;
    }
    
    /*--------------------------*
     *  set the vertical cycle
     *--------------------------*/
    else if (pId == setFrameVCycle) 
    {
        String s = pValue.toString(); 
        String sVal="";
        StringTokenizer st = new StringTokenizer(s,",");
        if (st.hasMoreTokens()) sName = st.nextToken() ;
        else return false ;
        objFrame of = (objFrame)hFrames.get(sName) ;
        if(of == null) return false ;
        if (st.hasMoreTokens())
        {
            sVal = st.nextToken() ;
            int i = 0 ;
            if(sVal.startsWith("/"))
            {
              i = Integer.parseInt(sVal.substring(1));
              iFrameVcycle = of.iWFrame / i ;
            }
            else
            {
              i = Integer.parseInt(sVal);
              iFrameVcycle = i ;
            }

            of.setFrameVCycle(iFrameVcycle);
            hFrames.put(sName,of);
            of.panel.repaint();
        }
        return true ;
    }         
     
    /*------------------
     *  rounded frame
     *-----------------*/
    else if(pId == pSetFrameRounded) 
    {
       String s = pValue.toString(); 
       String sVal="";
       StringTokenizer st = new StringTokenizer(s,",");
       if (st.hasMoreTokens()) sName = st.nextToken() ;
       else return false ;   
       if (st.hasMoreTokens())
       {
         sVal = st.nextToken() ;
         if(sVal.equalsIgnoreCase("true")) bRoundedFrame = true ;
         else bRoundedFrame = false ;
         objFrame of = (objFrame)hFrames.get(sName) ;
         if(of != null) 
         {
           of.setFrameRounded(bRoundedFrame);
           hFrames.put(sName,of);
           of.panel.repaint();           
         }
       }
       return true ;
    }
    
      /*---------------------
       *  transparent title
       *--------------------*/
      else if(pId == pSetFrameTextOpaque) 
      {
         String s = pValue.toString(); 
         String sVal="";
         StringTokenizer st = new StringTokenizer(s,",");
         if (st.hasMoreTokens()) sName = st.nextToken() ;
         else return false ;   
         if (st.hasMoreTokens())
         {
           sVal = st.nextToken() ;
           if(sVal.equalsIgnoreCase("true")) bFrameTitleOpaque = true ;
           else bFrameTitleOpaque = false ;
           objFrame of = (objFrame)hFrames.get(sName) ;
           if(of != null) 
           {
             of.bFrameTitleOpaque = bFrameTitleOpaque;
             hFrames.put(sName,of);
             of.panel.repaint();           
           }
         }
         return true ;
      }
      
    /*
    else if(pId == pPrintHashMap)
    { 
      for(int i=0; i < hFrames.size();i++)
          objFrame of = (objFrame)hFrames.get(i)
          // add object to hash map
          hFrames.put(sName,panel);      
      return true ;
    }
    */
    
    /*------------------*
     *  Show the frame  *
     *------------------*/
    else if( pId == pShowFrame)
    {
        String s = pValue.toString(); 
        StringTokenizer st = new StringTokenizer(s,",");
        if (st.hasMoreTokens()) sName = st.nextToken() ;
        else return false ;   
        objFrame of = (objFrame)hFrames.get(sName) ;
        if(of != null) 
        {
          of.setVisible(true);
          hFrames.put(sName,of);
          of.panel.repaint();
        }        
      return true;
    }   
    /*------------------*
     *  Hide the frame  *
     *------------------*/
    else if( pId == pHideFrame)
    {
        String s = pValue.toString(); 
        StringTokenizer st = new StringTokenizer(s,",");
        if (st.hasMoreTokens()) sName = st.nextToken() ;
        else return false ;   
        objFrame of = (objFrame)hFrames.get(sName) ;
        if(of != null) 
        {
          of.setVisible(false);
          hFrames.put(sName,of);
          of.panel.repaint();          
        }        
        return true;
    }

      /*----------------------*
       *  Remove given frame  *
       *----------------------*/
      else if( pId == pRemoveFrame)
      {
          String s = pValue.toString(); 
          StringTokenizer st = new StringTokenizer(s,",");
          if (st.hasMoreTokens()) sName = st.nextToken() ;
          else return false ;   
          objFrame of = (objFrame)hFrames.get(sName) ;
          if(of != null) 
          {
             this.getParent().remove(of.panel) ;
          } 
          hFrames.remove(sName);
          return true;
      }
      
      /*----------------------*
       *   Remove all frames  *
       *----------------------*/
      else if( pId == pRemoveAllFrames)
      {
          String str="", s = pValue.toString(); 
          Set set = hFrames.keySet();
          Iterator itr = set.iterator();
          while (itr.hasNext()) {
            str = (String)itr.next();
            System.out.println(str + ": " + hFrames.get(str));
            objFrame of = (objFrame)hFrames.get(str) ;
            if(of != null) 
            {
               System.out.println("Frame:"+of.sName);
               this.getParent().remove(of.panel) ;
            }        
          }
          hFrames.clear();
          return true;
      }
    else
    {
      return super.setProperty(pId, pValue);
    }
  } 

 /*-----------------------------------
  *  Class to render the FrameBorder
  *----------------------------------*/
 class FrameBorder extends AbstractBorder 
  {
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) 
    {
      // get the component values
      objFrame of = (objFrame)hFrames.get(c.getName()) ;
      if(of == null) return ;
      
      Graphics2D g2 = (Graphics2D) g ;
      String sFrameTitle = of.sFrameTitle ;      
      FontMetrics fm = g2.getFontMetrics(of.fFrameFont);
      Rectangle2D rect = fm.getStringBounds(of.sFrameTitle, g2);
      int  fWidth=1 ;
      if(of.iFrameWidth > 1) fWidth = (int)of.iFrameWidth / 2 ;
      int  iWidth  = width -  of.iFrameWidth ;
      int  iHeight = height - of.iFrameWidth ;
      int  iDec = (int)(rect.getHeight()/2);
      int  iTWidth = (int)rect.getWidth()/2 ;
      // frame border bounds
      int fX=x, fY=y, fW=width-(of.iFrameWidth*2), fH = height-(of.iFrameWidth*2);
      int  iX=0, iY=0 ;
      //
      // Title alignment
      // ------
      //   TOP
      // ------
      if(of.sFramePosition.equalsIgnoreCase("T"))
      {
        fX=x; fY=y+iDec; fW=width; fH=height-iDec;
        if(of.iFrameWidth > 1)
        {
          fX += fWidth ;
          fY += fWidth ;
          fW -= of.iFrameWidth ;
          fH -= of.iFrameWidth ;
        }
        else
        {
         fW -= 1;
         fH -= 1 ;
        }
        iX = (int)width/2-iTWidth ;
        iY = iDec + (int)iDec/2 + (int)of.iFrameWidth ;
        if(of.sFrameAligment.equalsIgnoreCase("L")) iX = x+10 ;
        else if(of.sFrameAligment.equalsIgnoreCase("R")) iX = iWidth - (int)rect.getWidth() - 10 ;
      }
      // ----------
      //   BOTTOM
      // ----------
      else if(of.sFramePosition.equalsIgnoreCase("B"))
      {
        fX=x; fY=y; fW=width-(of.iFrameWidth*2); fH=height-iDec-(of.iFrameWidth*2);
        if(of.iFrameWidth > 1)
        {
          fX += fWidth ;
          fY += fWidth ;
          fW -= of.iFrameWidth ;
          fH -= of.iFrameWidth ;
        }        
        else
        {
         fW -= 1;
         fH -= 1 ;
        }
        iX = (int)width/2-iTWidth ;
        iY = height - (int)of.iFrameWidth -(int)iDec/2 ;
        if(of.sFrameAligment.equalsIgnoreCase("L")) iX = x+10 ;
        else if(of.sFrameAligment.equalsIgnoreCase("R")) iX = iWidth - (int)rect.getWidth() - 10 ;
      }      

      // --------
      //   LEFT
      // --------
      else if(of.sFramePosition.equalsIgnoreCase("L"))
      {
        fX=x + iDec;
        fY=y; 
        fW=width-1-iDec-of.iFrameWidth; 
        fH=height-1-(of.iFrameWidth*2); 
        if(of.iFrameWidth > 1)
        {
          fY += fWidth ;
          fW -= fWidth ;
          fH -= of.iFrameWidth ;
        }        
        iX = (int)rect.getHeight()/2 + 4 ;
        iY = (int)rect.getWidth() + 5 + of.iFrameWidth;
        //if(of.sFrameAligment.equalsIgnoreCase("L")) iX = x+10 ;
        //else if(of.sFrameAligment.equalsIgnoreCase("R")) iX = iWidth - (int)rect.getWidth() - 10 ;
      }      
      
      // ---------
      //   RIGHT
      // ---------
      else if(of.sFramePosition.equalsIgnoreCase("R"))
      {
        fX=x; fY=y; fW=width-(of.iFrameWidth*2); fH=height-(of.iFrameWidth*2); 
        if(of.iFrameWidth > 1)
        {
          fX += fWidth ;
          fY += fWidth ;
          fW -= of.iFrameWidth ;
          fH -= of.iFrameWidth ;
        }        
        else
        {
         fW -= iDec;
         fH -= 1 ;
        }
        iX = width - ((int)rect.getHeight()/2 + 4);
        iY = 8 + of.iFrameWidth;
        //if(of.sFrameAligment.equalsIgnoreCase("L")) iX = x+10 ;
        //else if(of.sFrameAligment.equalsIgnoreCase("R")) iX = iWidth - (int)rect.getWidth() - 10 ;
      }      
      
      // ----------------
      // frame background
      // ----------------
      if(of.cFrameGradient1 != null || of.cFrameGradient2 != null) 
      {
        // gradient background ?
        if(of.cFrameGradient2 != null) 
        {
          GradientPaint gp = null ;
          
          if(of.iFrameHcycle + of.iFrameVcycle > 0)
          { 
             gp = new GradientPaint(0,0,of.cFrameGradient1,of.iFrameHcycle,of.iFrameVcycle,of.cFrameGradient2,true);
          }
          else
          {
            if(of.igrDir == LeftToRight)
            {
              gp = new GradientPaint(0,0,of.cFrameGradient1,iWidth,iHeight,of.cFrameGradient2);
            }
            else if(of.igrDir == RightToLeft)
            {
              gp = new GradientPaint(iWidth,iHeight,of.cFrameGradient1,0,0,of.cFrameGradient2);
            }
            else if(of.igrDir == UpToDown) // default
            {
              //gp = new GradientPaint(2,iHeight/2,of.cFrameGradient1,2,iHeight,of.cFrameGradient2);
              gp = new GradientPaint(0,0,of.cFrameGradient1,0,iHeight,of.cFrameGradient2);
            }        
            else if(igrDir == DownToUp)
            {
              gp = new GradientPaint(0,iHeight,of.cFrameGradient1,0,0,of.cFrameGradient2);
            }            
          }
          g2.setPaint(gp);
        }
        else g2.setColor(of.cFrameGradient1);
        
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, of.fTransparency));
        if(of.bRoundedFrame) g2.fillRoundRect(fX, fY, fW, fH,20,20);
        else g2.fillRect(fX, fY, fW, fH);
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
      }
        
      // ----------------
      //   frame border
      // ----------------
      g2.setStroke(new BasicStroke((float)of.iFrameWidth)); 
      // shadow
      if((of.cFrameShadow != null) && (of.iFrameWidth > 1))
      {
        g2.setColor (of.cFrameShadow) ; 
        if(of.bRoundedFrame) g2.drawRoundRect ( fX+(int)of.iFrameWidth/2 , fY+(int)of.iFrameWidth/2, fW, fH, 20, 20) ;
        else g2.drawRect ( fX+(int)of.iFrameWidth/2 , fY+(int)of.iFrameWidth/2, fW, fH ) ;
      }
      //frame
      g2.setColor (of.cFrameColor) ; 
      if(of.bRoundedFrame) g2.drawRoundRect ( fX, fY, fW, fH , 20, 20) ;
      else g2.drawRect ( fX, fY, fW, fH ) ;

      // control frame
      //g2.setColor (Color.black) ; 
      //g2.drawRect ( x, y, width, height ) ;
        
      // ---------------
      //   frame title
      // ---------------
      if(of.sFrameTitle != null )
      {
        g2.setFont(of.fFrameFont);
        if(of.cFrameTitleBack == null)  g2.setColor(VB.getParent().getBackground()) ;
        else g2.setColor(of.cFrameTitleBack);
        
        AffineTransform aT = g2.getTransform();
        AffineTransform at = new AffineTransform();
        at.setToTranslation(iX, iY);
        g2.transform(at);
        
        if(of.sFramePosition.equalsIgnoreCase("L")) 
        {
          at.setToRotation(3*(Math.PI / 2.0));
          g2.transform(at);
        }
        else if(of.sFramePosition.equalsIgnoreCase("R")) 
        {
          at.setToRotation(-3 * (Math.PI / 2.0));
          g2.transform(at);
        }

        if(! of.bFrameTitleOpaque)
        {
          g2.drawString(of.sFrameTitle, -4, 1);
          g2.drawString(of.sFrameTitle, -4, 0);
          g2.drawString(of.sFrameTitle, -2, 1);
          g2.drawString(of.sFrameTitle, -2, 0);
          g2.drawString(of.sFrameTitle, -1, -1);
          g2.drawString(of.sFrameTitle,  0, -1);
          g2.drawString(of.sFrameTitle,  1, -1);
          g2.drawString(of.sFrameTitle, -1, 1);
          g2.drawString(of.sFrameTitle,  0, 1);
          g2.drawString(of.sFrameTitle,  1, 1);
          g2.drawString(of.sFrameTitle,  2, -1);
          g2.drawString(of.sFrameTitle,  2, 0);
          g2.drawString(of.sFrameTitle,  4, -1);
          g2.drawString(of.sFrameTitle,  4, 0);          
        }
        else
          g2.fillRect ( -4 , -(int)rect.getHeight() , (int)rect.getWidth()+4 , (int)rect.getHeight()+4) ;

        g2.setColor(of.cFrameTitleFore);
        
        // control basis point
        //g2.setColor(Color.black);
        //g2.drawRect(0,0,2,2);
        
        g2.drawString(of.sFrameTitle, 0.0f, 0.0f);
        g2.setTransform(aT); 

      }
    }
    public Insets getBorderInsets ( ) 
    {
      return new Insets (1,1,1,1) ;
    }
  }

  /*--------------------------------------------*
   *   Object to handle the frame description   *
   *--------------------------------------------*/
  class objFrame extends Object {

       String  sName             = "" ;
       JComponent    panel       = null ;
       int     igrDir            = LeftToRight ;
       Color   cFrameColor       = Color.gray ;
       Color   cFrameShadow      = Color.lightGray ;
       Color   cFrameTitleFore   = Color.black ;
       Color   cFrameTitleBack   = null ;
       Color   cFrameGradient1   = null ;
       Color   cFrameGradient2   = null ;
       String  sFrameTitle       = null ;
       String  sFrameAligment    = "C" ;
       String  sFramePosition    = "T" ;
       int     iFrameWidth       = 2 ;
       int     iWFrame           = 0 ;
       int     iHFrame           = 0 ;
       float   fTransparency     = .5f ;
       boolean bRoundedFrame     = false ;
       boolean bFrameTitleOpaque = false ;
       boolean bVisible          = true ;
       int     x=-1, y=-1, w=-1, h=-1 ;
       int     iFrameHcycle=0, iFrameVcycle=0 ;
       Font    fFrameFont       = new Font("Verdana", Font.BOLD,14);

       objFrame(String sName, JComponent panel) {
           this.sName = sName ;
           this.panel = panel ;
       }

       private void setFrameTextAlign(String sPos,String sAlign) {
           this.sFramePosition = sPos ;
           this.sFrameAligment = sAlign ;
       } 
       private void setFrameRounded(boolean b) {
           this.bRoundedFrame = b ;
       }       
       private void setVisible(boolean b) {
           this.bVisible = b ;
           this.panel.setVisible(b);
       }       
       private void setFrameHCycle(int i) {
          this.iFrameHcycle = i ;
       }  
       private void setFrameVCycle(int i) {
          this.iFrameVcycle = i ;
       }         
       private void SetFrameGradOrient(int i) {
          this.igrDir = i ;
       }           
       private void SetFrameWidth(int i) {
          this.iFrameWidth = i ;
       }           
       private void setFrameTitle(String s) {
          this.sFrameTitle = s ;
       }           
       private void setFrameText(String sTitle, String sAlign) {
           this.sFrameTitle    = sTitle ;
           this.sFrameAligment = sAlign ;
       }
       private void setBounds(int x, int y, int w, int h) {
           this.x = x ;
           this.y = y ;
           this.w = w ;
           this.h = h ;
           this.panel.setBounds(x,y,w,h);
       }
       private void setFrameColors(Color c1, Color c2) {
          this.cFrameColor  = c1 ;
          this.cFrameShadow = c2 ;
       }       
       private void setFrameBackground(Color c1, Color c2, float f) {
         this.cFrameGradient1 = c1 ;
         this.cFrameGradient2 = c2 ;
         this.fTransparency = f ;
       }
       private void setFrameTitleColors(Color c1, Color c2) {
         this.cFrameTitleFore = c1 ;
         if(c2 != null) this.cFrameTitleBack = c2 ;
       }              
       private void setFrameFont(Font f) {
         this.fFrameFont = f ;
       }       
  }
  
  /*----------------------------------------*
   *  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 ;
  }

    
   /*--------------------------------*
    *   Component to show the frame  *
    *--------------------------------*/
   class myPanel extends JComponent
   {
      public myPanel()
      {
      }

        
       public void update(Graphics g)
       {
         paint(g);
       }
       
   }
    
} // frame

