/*
** 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;

import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import luxor.config.*;
import luxor.core.*;
import luxor.event.*;
import luxor.spi.*;
import luxor.status.*;
import luxor.*;

public class XulInput
{
   static Logger T = Logger.getLogger( XulInput.class );

   private NInput _comp;
   /**
    *  aka controller, parent
    */
   private XulForm _form;

   /**
    *  validation handlers
    */
   private ArrayList _handler = new ArrayList();

   private String _id;

   private Validator _validator;

   public XulInput( XulForm form, String id )
   {
      _form = form;
      _id = id;

      // register input control/element with xul form
      form.addInput( this );

      _validator = new Validator( this );
   }

   public void setChecked( boolean checked )
   {
      if( checked )
         _comp.setText( "true" );
      else
         _comp.setText( "false" );
   }

   public void setComponent( NInput comp )
   {
      _comp = comp;
      _comp.addFocusListener(
         new FocusListener()
         {
            public void focusGained( FocusEvent e )
            {
               onFocusGained();
            }

            public void focusLost( FocusEvent e )
            {
               onFocusLost();
            }
         } );
   }

   public void setText( String text )
   {
      // todo: should i differentiate between populate and setText

      _comp.setText( text );
      updateValidationStatus();
   }

   /**
    *  help id consists of panel id + input id e.g. extension.href cut of _PANEL
    *  panel id suffix cut of _INPUT input id suffix
    */
   public String getHelpId()
   {

      String formId = _form.getId();
      if( formId.endsWith( "_PANEL" ) )
         formId = formId.substring( 0, formId.length() - 6 );

      String inputId = getId();
      if( inputId.endsWith( "_INPUT" ) )
         inputId = inputId.substring( 0, inputId.length() - 6 );

      return formId + "." + inputId;
   }

   public String getId()
   {
      return _id;
   }

   public JComponent getJComponent()
   {
      if( _comp != null )
         return _comp.getJComponent();
      else
         return null;
   }

   /**
    *  return field name; helpful for error reporting
    */
   public String getName()
   {
      JLabel label = _comp.getLabel();
      if( label == null )
         return getId();
      else
      {
         String labelText = label.getText().trim();

         // cut off trailing colon if there is any
         if( labelText.endsWith( ":" ) )
            labelText = labelText.substring( 0, labelText.length() - 1 );

         return labelText;
      }
   }

   public String getText()
   {
      return _comp.getText();
   }

   public Validator getValidator()
   {
      return _validator;
   }

   /**
    *  convenience methods for checkboxes
    */
   public boolean isChecked()
   {
      if( _comp.getText().equalsIgnoreCase( "true" ) )
         return true;
      else
         return false;
   }

   public boolean isValid()
   {
      return getValidator().isValid();
   }

   public void addValidationHandler( XulInputValidationHandler handler )
   {
      _handler.add( handler );
   }

   public void onFocusGained()
   {
      T.debug( "focusGained() " + getId() );

      _form.fireFocusGained( this );
   }

   public void onFocusLost()
   {
      T.debug( "focusLost() " + getId() );

      // todo: make validation dependent on data change (performance feature)

      updateValidationStatus();

      _form.fireFocusLost( this );
   }

   private void updateValidationStatus()
   {
      validate();

      JLabel label = _comp.getLabel();
      if( label == null )
         return;

      if( !isValid() )
      {
         XulDefaults def = XulDefaults.getXulDefaults();

         label.setIcon( def.getErrorIcon() );
      }
      else
      {
         label.setIcon( null );
         // make error icon disappear
      }
   }

   private void validate()
   {
      getValidator().clearErrors();

      if( _handler.size() == 0 )
         return;

      for( Iterator it = _handler.iterator(); it.hasNext();  )
      {
         XulInputValidationHandler handler = ( XulInputValidationHandler ) it.next();
         handler.validate( this );
      }

      T.debug( "isValid=" + isValid() );
   }

}