package nxm.sys.libg;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

import nxm.sys.inc.MessageHandler;
import nxm.sys.inc.ProvisionalUseOnly;
import nxm.sys.lib.Shell;

/**
  A class to display a block of text.

  @author Jeff Schoen
*/
public class GText extends GWidget {

  private MJTextArea  mjtext;
  private JScrollPane scrollPane;
  /** Enable code block intended to fix timing issue with text area width */
  private static boolean fixTimingIssueWithTextWidth = true;

  /**
     Instantiate a new Text Area, initialize the parameters, and open
     the graphics panel.
     @param parent the parent object
     @param name the name of this MJTextArea
     @param text the text to be displayed
     @param aw the width
     @param ah the height
     @param flags the widget flags
     @param mh the MessageHandler
   */
  public GText (Object parent, String name, String text, int aw, int ah, int flags, MessageHandler mh) {
    super("GText",parent,name,flags,mh);
    open (name, aw, ah, text);
    addTo (parent);
  }

  /**
     Open the graphics window for this MJTextArea with the given name.
     This MJTextArea will be sized according to the given width and height,
     and will display the given text.
     @param name the name of this MJTextArea
     @param aw the width
     @param ah the height
     @param text the text to be displayed
   */
  public void open (String name, int aw, int ah, String text) {
    open(); // get text sizes
    super.open (name,aw*tw,ah*th+ta);
    setupTextArea(text,ah,aw);
  }

  /**
   * Setup the text area
   * @param text Text for the area
   * @param ah Area height (i.e. rows to display)
   * @param aw Area width (i.e. columns to display)
   */
  public void setupTextArea (String text, int ah, int aw) {
    if (headless) return; // Since NeXtMidas 3.5.0. Skip if in Headless state. BUG 2817
    mjtext = new MJTextArea (text,ah,aw);
    mjtext.setEditable(false);
    // The widget theme is not yet set here, so I override the setWidgetTheme(..) method  to
    // affect the input text colors
    mjtext.setBackground(theme.cwbg);
    mjtext.setForeground(theme.cwfg);
//      refresh(); May want to add a refresh here since 3.9.0

    // JWB: windows and Solaris do not size the scroll pane properly so for now it is only Linux
    if (Shell.osname.equals("Linux")) {
      scrollPane = new JScrollPane(mjtext);
      scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
      scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
      panel.add(scrollPane);
    } else {
      panel.add(mjtext);
    }
    setBounds();
  }

  @ProvisionalUseOnly("Treat this as protected and should only be called by subclass paintComponent methods")
  @Override
  public void paintComponent (Graphics g) {
    getMJTextArea().setAttributesGW(this); // Is this needed, it looks to be changing the shadow color of the text box. NXM-3213 since 3.9.0 Check test_lookandfeel
    super.paintComponent(g);
    paintTitle(g);
  }

  /** Method to perform the the painting of the Title.
   *  @param g Graphics object
   *  @since NeXtMidas 3.9.0
   */
  public void paintTitle (Graphics g) {
    if (g==null || bw==0) return;
    int bf=SB_DEF;
    if (is(INLINE)) bf=SB_FLAT_SHADE;
    shadowbox (g,0,0,pos.w,pos.h,bf);
    if (titleh>0) {
      int lh = bw+titleh;
      shadowbox (g,0,0,pos.w,lh,SB_SHADE);  // the shadowbox around the title
      g.setColor(isEnabled()? theme.cwfh : disabledColor);  // if disabled, use disabled color (Bug 2323)
      g.drawString(title,pos.w/2-titlew/2,titleh/2+ta/2); // draw the test in the title bar
    }
    g.setColor(isEnabled()? theme.cfg : disabledColor);  // if disabled, use disabled color (Bug 2323)
    panel.revalidate();// this is used to make sure everything is showing and lining up correctly
  }

  /** Set the widget theme for this text widget and the MJTextArea.
      @param o The theme in String, Table or Object form
  */
  public void setWidgetTheme(Object o) {
    // jph - I added this method because -- Seems that the widget theme is not yet set in the open()
    //       method below , so this MAY have no thus I override the setWidgetTheme(..) method in GWidget
    //       to affect the input text colors
    super.setWidgetTheme(o);
    if (headless) return; // Since NeXtMidas 3.5.0. Skip if in Headless state. BUG 2817
    mjtext.setForeground(theme.getWidgetForeground());
    mjtext.setBackground(theme.getWidgetBackground());
  }

  public void resize (int mode) {
    super.resize(mode);
    setBounds();
  }

  private void setBounds () {
    mjtext.setBounds(bw,bw+titleh,pw,ph);
    if (scrollPane != null) {
      scrollPane.setBounds(bw,bw+titleh,pw,ph); // keep the scrollpane the same size as the textArea
    }
  }

  /** override MWindow.setBounds to handle compression */
  @Override
  public void setBounds (int x, int y, int w, int h) {
    super.setBounds(x, y, w, h);
    // the code below is intended to fix very intermittent issue NXM-3550
    // where a GText under a GLabel has old size information and is too narrow
    if (fixTimingIssueWithTextWidth) {
      // This issue only occurs when there is a visible scroll bar
      // Doing this update when there is not a visible scroll bar can
      // cause the text area to be drawn too low (gap at top)
      if ((scrollPane != null) && (scrollPane.getVerticalScrollBar().isVisible())){
        pw = w-bw-bw;
        ph = h-bw-bw-titleh;
        mjtext.setBounds(bw,bw+titleh,pw,ph);
        scrollPane.setBounds(bw,bw+titleh,pw,ph);
      }
    }
  }

  public void setValue (String value) {
    mjtext.setText(value);
  }

  public Object getValue () {
    return mjtext.getText();
  }

  public void setTheme (Theme theme) {
    super.setTheme(theme);
    if (mjtext != null) { // Since NeXtMidas 3.5.0 Proceed only if not null BUG 2817
      mjtext.setBackground(theme.cwbg);
      mjtext.setForeground(theme.cwfg);
    }
  }

  public boolean isStretchable() {
    return true;
  }

  /** Get the MJTextArea
   *  @return the MJTextArea */
  public MJTextArea getMJTextArea () {
    return mjtext;
  }

  /** Sets the color of the selected text
      @param c The color to set to
      @since NeXtMidas 2.9.0
   */
  public void setSelectedTextColor (Color c) {
    mjtext.setSelectedTextColor(c);
  }

  /** Gets the color of the selected text
      @return The color
      @since neXtMidas 2.9.0
   */
  public Color getSelectedTextColor () {
    return mjtext.getSelectedTextColor();
  }

  /** Sets the background selection color of the text area
      @param c The Color to set
      @since NeXtMidas 2.9.0
   */
  public void setSelectionColor (Color c) {
    mjtext.setSelectionColor(c);
  }

  /** Gets the background color of the text area selection
      @return The color
      @since NeXtMidas 2.9.0
   */
  public Color getSelectionColor () {
    return mjtext.getSelectionColor();
  }

  /** Sets the color of the selected text
      @param color The color to set to
      @since NeXtMidas 2.9.0
   */
  public void setSelectedTextColor (String color) {
    setSelectedTextColor(MColor.getColor(color));
  }

  /** Gets the color of the selected text
      @return The color
      @since neXtMidas 2.9.0
   */
  public String getSelectedTextColorString () {
    return MColor.toString(getSelectedTextColor());
  }

  /** Sets the background selection color of the selection
      @param c The Color to set
      @since NeXtMidas 2.9.0
   */
  public void setSelectionColor (String c) {
    setSelectionColor(MColor.getColor(c));
  }

  /** Gets the background color of the selection
      @return The color
      @since NeXtMidas 2.9.0
   */
  public String getSelectionColorString () {
    return MColor.toString(getSelectionColor());
  }

  /** Turn off fix intended to fix timing error where text area does not
   *  get updated with correct width
   *
   *  @param useFix false to turn off fix
   *  @since NeXtMidas 3.9.3 for NXM-3550
   */
  @ProvisionalUseOnly ("temporary means of backing out fix")
  public static void setFixTimingIssueWithTextWidth(String useFix) {
    fixTimingIssueWithTextWidth = useFix.toLowerCase().equals("true");
  }

}
