Listing of Source ../source/GOF/GofHorLineIdentifier.java
package se.entra.phantom.server;

import java.util.StringTokenizer;
import java.util.Vector;

/**
 * This class identifies horizontal line controls for the Gui-on-the-fly, from unused GofHostFields.
 * @author J. Bergström
 */
public class GofHorLineIdentifier extends GofControlIdentifierAdapter implements PhantomControlType
{
  // ------------------
  // INSTANCE VARIABLES
  // ------------------

  /**
   * Minimum length to be considered as a horizontal line.
   * <p>
   * Defaults to 2.
   */
  private int horLineMinLength = 2;

  /** 
   * A vector containing all the characters that can build up a horizontal line.
   */
  private Vector<String> horLineChars = new Vector<String>( );

  // ----------------
  // INSTANCE METHODS
  // ----------------

  /**
   * Loads setting for the control from the server ini-file.
   * <p>
   * The characters that are allowed to be converted into a horizontal line are specified in the 
   * server.ini file. The setting might look like the one below. In this example, the only valid 
   * character is a hyphen.
   * <pre>
   *    horlinechars=-
   * </pre>
   * The minimum number of times that this character must be repeated, before it is considered a 
   * horizontal line, is also specified in the server.ini file.
   * <pre>
   *    horlineminlength=10
   * </pre>
   * @param confFile The server ini file.
   */
  @Override
  public void getControlSettings( IniFile confFile, String subsection )
  {
    String setting;
    setting = confFile.getData( subsection, "horlineminlength" );
    setHorLineMinLength( setting );

    setting = confFile.getData( subsection, "horlinechars" );
    parseHorLineChars( setting );
  }

  /**
   * Identifies all the horizontal line controls from the <code>GofHostFields</code>.
   * <p>
   * It will check for a GofHostField, that only consists of one, repeated character, and that 
   * character is one of the characters that has been specified as a valid character for the 
   * horizontal line. The number of times the character is repeated in the GofHostField must equal, 
   * or exceed, the minimum number specified in the server.ini.
   * <p>
   * The horizontal line will be created as a PhantomCRectangle, with a height of 1, and a depth of 1.
   * @param gofRuntime        The GuiOnTheFlyRuntime instance.
   * @param areaIdentifier    The areaIdentifier in which the entry fields should be identified..
   * @param phantomHostScreen The Phantom host screen corresponding to the host screen.
   * @param hostScreen        The host screen that we are trying to build a GOF panel for.
   * @param newPanel          The newly created Gui-on-the-fly runtime panel.
   */
  @Override
  public void identifyCtrls( GuiOnTheFlyRuntime gofRuntime,
                             GofHostAreaIdentifier areaIdentifier, 
                             PhantomHostScreen phantomHostScreen, 
                             HostScreen hostScreen,
                             PhantomPanelData templPanel, 
                             PhantomPanelData newPanel,
                             int offsetX,
                             int offsetY )
  {
    this.templPanel = templPanel;

    Vector<GofHostField> gofHostFields = areaIdentifier.getAreasGofHostFields( );

    for( int i1 = 0, s1 = gofHostFields.size( ); i1 < s1; i1++ )
    {
      GofHostField gofHostField = gofHostFields.elementAt( i1 );
      if( gofHostField.hasBeenProcessed == false && 
          gofHostField.isProtected( ) == true && 
          gofHostField.isEmpty( ) == false && 
          gofHostField.getCx( ) >= horLineMinLength )
      {
        String text = gofHostField.getText( );

        for( int i2 = 0, s2 = horLineChars.size( ); i2 < s2; i2++ )
        {
          String c = horLineChars.elementAt( i2 );
          if( consistsOf( text, c ) == true )
          {
            int x = gofHostField.getX( );
            int y = gofHostField.getY( );
            int cx = gofHostField.getCx( );

            // Create the base control.
            PhantomControlBase bc = new PhantomControlBase( GOF_MARGINX + ( x - offsetX ) * GOF_STEPX,
                                                            GOF_MARGINY + ( y - offsetY ) * GOF_STEPY + GOF_STEPY / 2,
                                                            cx * GOF_GUIUNITX,
                                                            1,
                                                            CTRLTYPE_RECT );

            // Create the output text.
            PhantomCRectangle r = new PhantomCRectangle( newPanel, bc );
            r.depth = 1;

            // Add it in the panel.
            newPanel.addControl( r );
            areaIdentifier.addControl( r );
            gofHostField.hasBeenProcessed = true;
          }
        }
      }
    }
  }

  /**
   * Sets the minimum length accepted as a horizontal line. If the value from the ini-file
   * can't be converted to a numeric value, the default length 2 will be used.
   * @param setting The minimum length as a <code>String</code> as specified in the server.ini file.
   */
  private void setHorLineMinLength( String setting )
  {
    if( setting != null && setting.equals( "" ) == false )
    {
      try
      {
        horLineMinLength = Integer.valueOf( setting ).intValue( );
      }
      catch( NumberFormatException e )
      {
        horLineMinLength = 2;
      }
    }
  }

  /**
   * Parse the string from the server.ini file containing the characters
   * that are allowed in a horizontal line.
   * <p>
   * These characters are stored in the <code>Vector</code> horLineChars.
   */
  private void parseHorLineChars( String linechars )
  {
    if( linechars == null || linechars.equals( "" ) )
      return;

    StringTokenizer st = new StringTokenizer( linechars, ", " );
    while( st.hasMoreTokens( ) )
    {
      String s = st.nextToken( ).trim( );
      if( s.equals( "" ) == false )
        horLineChars.addElement( s );
    }
  }

  /**
   * Checks if a string consists of a specified character, and no other characters.
   * @param text The text string to check.
   * @param c    The character to search for, as a <code>String</code>.
   * @return <code>true</code> if the whole string was made up of the character,
   *         <code>false</code> otherwise.
   */
  private boolean consistsOf( String text, String c )
  {
    if( text == null )
      return false;
    text = text.trim( );
    if( text.equals( "" ) )
      return false;

    if( c == null || c.equals( "" ) )
      return false;

    char c1 = c.charAt( 0 );
    for( int i = 0, s = text.length( ); i < s; i++ )
    {
      char c2 = text.charAt( i );
      if( c2 != c1 )
        return false;
    }
    return true;
  }
}