/*
** Luxor - XML User Interface Language (XUL) Toolkit
** Copyright (c) 2001, 2002 by Gerald Bauer
**
** This program is free software.
**
** You may redistribute it and/or modify it under the terms of the GNU
** General Public License as published by the Free Software Foundation.
** Version 2 of the license should be included with this distribution in
** the file LICENSE, as well as License.html. If the license is not
** included with this distribution, you may find a copy at the FSF web
** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/

package luxor.swing;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.*;
import javax.swing.*;
import luxor.core.*;
import luxor.core.table.*;
import luxor.spi.*;
import luxor.status.*;

public class TablePeer extends AbstractContainer
{
   static Logger T = Logger.getLogger( TablePeer.class );

   private JPanel _panel;

   public TablePeer( TableDef def, JComponentResolver resolver )
   {
      super( def );

      _panel = new JPanel();
      _panel.setLayout( new GridBagLayout() );

      // todo: read width attribute

      Iterator rowIt = def.getRowDefs().iterator();
      int y = 0;
      while( rowIt.hasNext() )
      {
         TableRowDef row = ( TableRowDef ) rowIt.next();

         Iterator dataIt = row.getDataDefs().iterator();
         int x = 0;
         while( dataIt.hasNext() )
         {
            TableDataDef cell = ( TableDataDef ) dataIt.next();

            int colspan = setupCell( cell, _panel, x, y, resolver );
            x += colspan;
         }
         y++;
      }

      resolveReferences();
   }

   private int setupCell( TableDataDef def, JPanel panel, int x, int y, JComponentResolver resolver )
   {
      int colspan = def.getColSpan();
      int rowspan = def.getRowSpan();

      // possible values:
      // horz = MAX, LEFT, CENTER, RIGHT
      // vert = MAX, TOP, MIDDLE, BOTTOM - should i rename middle to center??

      int horz = def.getAlignAttribute( Xul.Attribute.HORZ, Xul.Align.LEFT );
      int vert = def.getAlignAttribute( Xul.Attribute.VERT, Xul.Align.MIDDLE );

      GridBagConstraints con = new GridBagConstraints();

      con.gridx = x;
      con.gridy = y;
      con.weightx = 0;
      con.weighty = 0;

      if( horz == Xul.Align.MAX && vert == Xul.Align.MAX )
      {
         con.fill = GridBagConstraints.BOTH;
         con.weightx = 1.0;
         con.weighty = 1.0;

         horz = Xul.Align.CENTER;
         vert = Xul.Align.MIDDLE;
      }
      else if( horz == Xul.Align.MAX )
      {
         con.fill = GridBagConstraints.HORIZONTAL;
         con.weightx = 1.0;

         horz = Xul.Align.CENTER;
      }
      else if( vert == Xul.Align.MAX )
      {
         con.fill = GridBagConstraints.VERTICAL;
         con.weighty = 1.0;

         vert = Xul.Align.MIDDLE;
      }
      else
      {
         con.fill = GridBagConstraints.NONE;
      }

      if( horz == Xul.Align.LEFT && vert == Xul.Align.TOP )
      {
         con.anchor = GridBagConstraints.NORTHWEST;
      }
      else if( horz == Xul.Align.LEFT && vert == Xul.Align.MIDDLE )
      {
         con.anchor = GridBagConstraints.WEST;
      }
      else if( horz == Xul.Align.LEFT && vert == Xul.Align.BOTTOM )
      {
         con.anchor = GridBagConstraints.SOUTHWEST;
      }
      else if( horz == Xul.Align.CENTER && vert == Xul.Align.TOP )
      {
         con.anchor = GridBagConstraints.NORTH;
      }
      else if( horz == Xul.Align.CENTER && vert == Xul.Align.MIDDLE )
      {
         con.anchor = GridBagConstraints.CENTER;
      }
      else if( horz == Xul.Align.CENTER && vert == Xul.Align.BOTTOM )
      {
         con.anchor = GridBagConstraints.SOUTH;
      }
      else if( horz == Xul.Align.RIGHT && vert == Xul.Align.TOP )
      {
         con.anchor = GridBagConstraints.NORTHEAST;
      }
      else if( horz == Xul.Align.RIGHT && vert == Xul.Align.MIDDLE )
      {
         con.anchor = GridBagConstraints.EAST;
      }
      else if( horz == Xul.Align.RIGHT && vert == Xul.Align.BOTTOM )
      {
         con.anchor = GridBagConstraints.SOUTHEAST;
      }
      else
      {
         Xul.error( "unsupported horz/vert combination" );
         T.debug( " horz=" + horz );
         T.debug( " vert=" + vert );
      }

      con.gridwidth = colspan;
      con.gridheight = rowspan;

      JComponent jcomp;
      List compDefs = def.getComponentDefs();

      if( compDefs.size() == 0 )
      {
         jcomp = new JLabel( "" );
      }
      else if( compDefs.size() == 1 )
      {
         NComponentFactory f = ( NComponentFactory ) compDefs.get( 0 );
         NComponent comp = f.createNComponent( resolver );
         addComponent( comp );

         jcomp = comp.getJComponent();
      }
      else
      {
         // squeeze components into a panel
         JPanel cell = new JPanel();
         cell.setLayout( new FlowLayout( FlowLayout.LEFT ) );

         Iterator compDefIt = compDefs.iterator();
         while( compDefIt.hasNext() )
         {
            NComponentFactory f = ( NComponentFactory ) compDefIt.next();
            NComponent comp = f.createNComponent( resolver );
            addComponent( comp );

            cell.add( comp.getJComponent() );
         }
         jcomp = cell;
      }

      panel.add( jcomp, con );

      return colspan;
   }

   public JComponent getJComponent()
   {
      return _panel;
   }

   public boolean useMinHeight()
   {
      return false;
   }

   public boolean useMinWidth()
   {
      return false;
   }
}