package com.dbxml.db.admin.swing;

/*
 * dbXML - Native XML Database
 * Copyright (C) 1999-2004  The dbXML Group, L.L.C.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id: PropertyPane.java,v 1.3 2004/07/21 00:44:32 bradford Exp $
 */

import java.awt.*;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.JPasswordField;
import javax.swing.JComponent;
import javax.swing.JComboBox;

/**
 * PropertyPane
 */

public class PropertyPane extends JPanel {
   private static final PropertyInfo[] EmptyPropertyInfo = new PropertyInfo[0];

   private GridBagLayout layoutGrid = new GridBagLayout();

   private JPanel pnlGrid = new JPanel();

   private Font font;
   private List properties = new ArrayList();
   private List labels = new ArrayList();
   private List editors = new ArrayList();
   private JLabel lblProperty = new JLabel();
   private JLabel lblValue = new JLabel();
   private Border brdProperty;
   private Border brdValue;
   private BorderLayout layoutThis = new BorderLayout();

   public PropertyPane() {
      try {
         jbInit();
      }
      catch(Exception ex) {
         ex.printStackTrace();
      }
   }

   void jbInit() throws Exception {
      brdProperty = BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.white,Color.white,new Color(124, 124, 124),new Color(178, 178, 178)),BorderFactory.createEmptyBorder(0,5,0,5));
      brdValue = BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.white,Color.white,new Color(124, 124, 124),new Color(178, 178, 178));
      lblProperty.setBorder(brdProperty);
      lblProperty.setHorizontalAlignment(SwingConstants.RIGHT);
      lblProperty.setText("Property");
      pnlGrid.setLayout(layoutGrid);
      this.setFont(new java.awt.Font("Dialog", 0, 10));
      this.setLayout(layoutThis);
      lblValue.setBorder(brdValue);
      lblValue.setText("Value");
      this.add(pnlGrid, BorderLayout.NORTH);
      pnlGrid.add(lblProperty,  new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
      pnlGrid.add(lblValue,    new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
   }

   public void addProperty(PropertyInfo property) {
      JLabel lbl = new JLabel();
      lbl.setFont(font);
      lbl.setHorizontalAlignment(JLabel.RIGHT);
      lbl.setText(property.getLabel());
      if ( property.isRequired() )
         lbl.setForeground(Color.red);

      PropertyEditor txt;
      switch ( property.getType() ) {
         case PropertyInfo.TYPE_PASSWORD:
            txt = new PasswordPropertyEditor();
            break;
         case PropertyInfo.TYPE_INT:
            txt = new IntPropertyEditor();
            break;
         case PropertyInfo.TYPE_FLOAT:
            txt = new FloatPropertyEditor();
            break;
         case PropertyInfo.TYPE_BOOLEAN:
            txt = new BooleanPropertyEditor();
            break;
         default:
            txt = new StringPropertyEditor();
            break;
      }

      txt.setText(property.getValue());

      JComponent comp = (JComponent)txt;
      comp.setFont(font);
      comp.addFocusListener(new FocusListener() {
         public void focusLost(FocusEvent e) {
            ((PropertyEditor)e.getSource()).stopEditing();
            checkValidity();
         }

         public void focusGained(FocusEvent e) {
            ((PropertyEditor)e.getSource()).selectAll();
         }
      });
      comp.addKeyListener(new KeyListener() {
         public void keyTyped(KeyEvent e) {
         }

         public void keyPressed(KeyEvent e) {
            switch ( e.getKeyCode() ) {
               case KeyEvent.VK_UP:
                  ((JComponent)e.getSource()).transferFocusBackward();
                  break;
               case KeyEvent.VK_DOWN:
                  ((JComponent)e.getSource()).transferFocus();
                  break;
            }
         }

         public void keyReleased(KeyEvent e) {
            PropertyEditor editor = (PropertyEditor)e.getSource();
            int idx = editors.indexOf(editor);
            if ( idx != -1 ) {
               PropertyInfo pi = (PropertyInfo)properties.get(idx);
               pi.setValue(editor.getText().trim());
            }
            checkValidity();
         }
      });

      properties.add(property);
      editors.add(txt);
      labels.add(lbl);

      pnlGrid.add(lbl, new GridBagConstraints(0, properties.size(), 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
      pnlGrid.add(comp, new GridBagConstraints(1, properties.size(), 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
   }

   public void setFont(Font font) {
      super.setFont(font);
      this.font = font;
      if ( lblProperty != null )
         lblProperty.setFont(font);

      if ( lblValue != null )
         lblValue.setFont(font);

      if ( editors != null ) {
         for ( int i = 0; i < editors.size(); i++ ) {
            ((JLabel)labels.get(i)).setFont(font);
            ((JTextField)editors.get(i)).setFont(font);
         }
      }
   }

   public PropertyInfo[] getProperties() {
      return (PropertyInfo[])properties.toArray(EmptyPropertyInfo);
   }

   public void addProperties(PropertyInfo[] properties) {
      for ( int i = 0; i < properties.length; i++ )
         addProperty(properties[i]);
      revalidate();
   }

   public void addProperties(List properties) {
      PropertyInfo[] pi = (PropertyInfo[])properties.toArray(EmptyPropertyInfo);
      addProperties(pi);
   }

   public void clearProperties() {
      properties.clear();
      editors.clear();
      pnlGrid.removeAll();
      pnlGrid.add(lblProperty,  new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
      pnlGrid.add(lblValue,    new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
      revalidate();
   }

   public boolean checkValidity() {
      for ( int i = 0; i < properties.size(); i++ ) {
         PropertyInfo pi = (PropertyInfo)properties.get(i);
         JTextField txt = (JTextField)editors.get(i);
         if ( pi.isRequired() && txt.getText().trim().length() == 0 )
            return false;
      }
      return true;
   }
}

