// Add/Strip Leading Spaces.java
// Cyno's Editor Plug-In

// Cynosure.X International
// 11-6-1997

// Copyright (C) 1997, 1998 by Chieh Cheng.
// All Rights Reserved.

package plug_ins;

import cynosurex.awt.*;
import cynosurex.util.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class AddStripLeadingSpaces extends Frame
  implements ActionListener, Runnable, TextListener, WindowListener
{
  // This variable specifies the string to be displayed
  // by Cyno's Editor.
  // This variable is required for all plug-ins.

  public final static String description = "Add/Strip Leading Spaces . . .";

  private final static boolean ADD = true;
  private final static boolean STRIP = false;

  private TextField t = new TextField (5);
  private Button b = new Button ("Add/Strip");
  private ShareData shared;

  private Thread thread = new Thread (this);

  // This constructor is the constructor
  // to be executed by Cyno's Editor.
  // This constructor is required for all plug-ins.

  public AddStripLeadingSpaces (ShareData shared)
  {
    super (description);
    this.shared = shared;
    setLayout (new FlowLayout ());
    setBackground (SystemColor.text);
    add (t);
    add (b);

    b.setEnabled (false);
    t.addActionListener (this);
    t.addTextListener (this);
    b.addActionListener (this);
    addWindowListener (this);

    pack ();

    Point p = shared.getTextArea ().getLocationOnScreen ();
    p.x -= 100;
    p.y -= 100;

    Location l = new Location (p, getSize ());

    setLocation (l);
    setVisible (true);

    thread.start ();
  }

  public void modify (int spaces, boolean mode)
  {
    EnhancedTextArea eta = shared.getTextArea ();
    int start = eta.getSelectionStart ();
    int end = eta.getSelectionEnd ();

    if (start != end)
    {
      String str = eta.getSelectedText ();
      StringTokenizer lines = new StringTokenizer (str, "\r\n", true);
      StringBuffer buffer = new StringBuffer ();

      Set lineBreakSet = new Set ();
      lineBreakSet.addElement ("\r");
      lineBreakSet.addElement ("\n");

      while (lines.hasMoreTokens ())
      {
        String line = lines.nextToken ();

        if (mode == ADD)
        {
          if (lineBreakSet.has (line))
            ;
          else
          {
            for (int i = 0; i < spaces; i++)
              buffer.append (' ');
          }
          buffer.append (line);
        }
        else
        {
          if (line.length () > spaces)
          {
            boolean blank = true;

            for (int i = 0; i < spaces; i++)
              blank = (blank && (line.charAt (i) == ' '));

            if (blank)
              buffer.append (line.substring (spaces));
            else
              buffer.append (line);
          }
          else
            buffer.append (line);
        }
      }

      eta.replaceRange (buffer.toString (), start, end);
      eta.select (start, start + buffer.toString ().length ());
    }
  }

  public void run ()
  {
    Thread thisThread = Thread.currentThread ();
    thisThread.setPriority (Thread.MIN_PRIORITY);

    while (thisThread == thread)
    {
      checkEnable ();

      Thread.yield ();
      try
      {
        Thread.sleep (2000); // in milliseconds
      }
      catch (InterruptedException e)
      {
      }
    }
  }

  private void checkEnable ()
  {
    String str = t.getText ();
    EnhancedTextArea eta = shared.getTextArea ();
    int i = eta.getSelectionStart ();
    int j = eta.getSelectionEnd ();

    if ((str != null) && (! str.equals ("")) && (i != j))
      b.setEnabled (true);
    else
      b.setEnabled (false);
  }

  public void actionPerformed (ActionEvent event)
  {
    if (b.isEnabled ())
    {
      String str = t.getText ();
      int spaces = 0;

      try
      {
        spaces = Integer.parseInt (str);
        if (spaces < 0)
          modify (Math.abs (spaces), STRIP);
        else
          modify (spaces, ADD);
      }
      catch (NumberFormatException e)
      {
        t.selectAll ();
      }
    }
  }

  public void textValueChanged (TextEvent e)
  {
    checkEnable ();
  }

  public void windowActivated (WindowEvent event)
  {
  }
  public void windowClosed (WindowEvent event)
  {
  }
  public void windowClosing (WindowEvent event)
  {
    thread = null;
    setVisible (false);
    dispose ();
  }
  public void windowDeactivated (WindowEvent event)
  {
  }
  public void windowDeiconified (WindowEvent event)
  {
  }
  public void windowIconified (WindowEvent event)
  {
  }
  public void windowOpened (WindowEvent event)
  {
  }
}
