//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// © Copyright IBM Corporation 2004, 2007
// All Rights Reserved.
//
// DESCRIPTION:
// LongestCommand - sample user-defined command (longest)
//----------------------------------------------------------------------------

package com.ibm.lpex.samples;

import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexDocumentLocation;
import com.ibm.lpex.core.LpexView;

/**
 * Sample command <b>longest</b> - locate the longest text line.
 * Run this command to locate the first longest, or next longer, visible text
 * line in the current view.  Trailing white space in the text is ignored.
 *
 * <p>Here is the LongestCommand
 * <a href="doc-files/LongestCommand.java.html">source code</a>.</p>
 *
 * <p>To run this sample:
 * <ul>
 *  <li>Define this user command via an editor preference page, where available,
 *   or from the editor command line:
 *    <pre>set commandClass.longest com.ibm.lpex.samples.LongestCommand</pre></li>
 *  <li>Run it from the editor command line:
 *    <pre>longest [next]</pre></li>
 * </ul></p>
 *
 * @see com.ibm.lpex.samples All the samples
 */
public class LongestCommand implements LpexCommand
{
 /**
  * Runs this command.
  * Positions the cursor on the first longest visible text line.
  *
  * @param lpexView the document view in which the command was issued
  * @param parameters optional "next" to start from the current element, or
  *                   "?" to display the syntax of this command
  */
 public boolean doCommand(LpexView lpexView, String parameters)
 {
  if (lpexView != null)
   {
    parameters = parameters.trim();
    if ("?".equals(parameters)) // command help
     {
      lpexView.doCommand("set messageText Syntax: longest [next]");
      return true;
     }

    // start from the beginning of the document / the current element
    int longestElement = "next".equals(parameters)? lpexView.currentElement() : 1;
    int longestLength = 0;

    // determine longest visible text (i.e., non-show) element
    int elements = lpexView.elements();
    LpexDocumentLocation loc = new LpexDocumentLocation(longestElement, 1);
    for (; loc.element < elements; loc.element++)
     {
      if (!lpexView.show(loc.element) && lpexView.queryOn("visible", loc))
       {
        int len = elementLength(lpexView, loc.element);
        if (len > longestLength)
         {
          longestLength = len;
          longestElement = loc.element;
         }
       }
     }

    // go there, unless there already
    if (longestElement != lpexView.currentElement())
     {
      int elementOfRow1 = lpexView.elementOfRow(1);
      lpexView.jump(longestElement, 1);

      // if new viewport, center this line on the screen
      lpexView.doCommand("screenShow view");
      if (elementOfRow1 != lpexView.elementOfRow(1))
       {
        lpexView.doCommand("set cursorRow " + (lpexView.queryInt("rows") / 2));
       }
     }

    // emphasize our big find
    lpexView.doCommand("set emphasisPosition 1");
    lpexView.doCommand("set emphasisLength " + longestLength);
   }

  return true;
 }

 // Returns a line's effective length (ignores trailing blanks and tabs).
 int elementLength(LpexView lpexView, int element)
 {
  String text = lpexView.elementText(element);
  int len = (text != null)? text.length() : 0;
  while (len > 0 && (text.charAt(len-1) == ' ' || text.charAt(len-1) == '\t'))
   {
    len--;
   }
  return len;
 }
}