/*

Freely Distributable Java Applets

Copyright (c) 1996-2001 The University of Texas
All Rights Reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

The GNU Public License is available in the file LICENSE, or you
can write to the Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
World Wide Web at http://www.fsf.org.

Author: Dogu Arifler and Brian Evans
Version: @(#)RegisterWindow.java	1.14  04/17/01

Department of Electrical and Computer Engineering
The University of Texas, Austin, TX 78712-1084

*/

package utexas.espl.weds.ui;

import java.awt.*;
import java.util.*;
import javax.swing.*;

/* Build a component with a text area and a title */
public class RegisterWindow extends JPanel {
    private JTextArea comArea;

    final int WINDOW_HEIGHT = 5;
    final int WINDOW_WIDTH = 32;
    final char HIGHLIGHT_CHAR = '*';

    // FIXME: These should not be hardcoded
    // Note that REGISTER_FIELD_WIDTH < ENTRY_FIELD_WIDTH
    final int REGISTER_FIELD_WIDTH = 14;
    final int ENTRY_FIELD_WIDTH = 16;
    final int ENTRIES_PER_LINE = 2;

    // Constructor
    public RegisterWindow( String title ) {
        comArea = new JTextArea(WINDOW_HEIGHT, WINDOW_WIDTH);
        comArea.setFont(new Font("Courier", Font.PLAIN, 12));
        comArea.setEditable( false );
        comArea.setLineWrap(true);
        comArea.setWrapStyleWord(true);
        JScrollPane areaScrollPane = new JScrollPane(comArea);
        areaScrollPane.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setBorder(
            BorderFactory.createCompoundBorder(
                BorderFactory.createCompoundBorder(
                                BorderFactory.createTitledBorder(title),
                                BorderFactory.createEmptyBorder(5,5,5,5)),
                areaScrollPane.getBorder()));
        add(areaScrollPane);
    }

    // Append text in the text field without parsing the text
    public void appendText(String text) {
        comArea.append(text);
    }

    // Reads the text in the text field
    public String getText() {
        return comArea.getText();
    }

    // Sets the text in the text field
    public void setText( String text ) {
        comArea.setText( text );
    }

    // Pad on the left with spaces to fill out the register field
    // and then pad on the right with spaces to fill out the field
    // Conditionally highlight the text accrording to highlightFlag
    // FIXME: Reuse the code CommandMenu.parseLine to parse the
    // old and new test into an array of strings and then compare
    // entries to determine highlighting.
    private String formatText(int lineLength, String lineOfText,
                              boolean highlightFlag) {
        StringBuffer newText = new StringBuffer();
        int j;
        for (j = REGISTER_FIELD_WIDTH - lineLength; j > 0; j-- ) {
            newText.append(" ");
        }
        if (lineLength > 0) {
            newText.append(lineOfText);
        }
        if ( highlightFlag ) {
            newText.append(HIGHLIGHT_CHAR);
        }
        else {
            newText.append(" ");
        }
        for (j = ENTRY_FIELD_WIDTH - REGISTER_FIELD_WIDTH - 1; j > 0; j-- ) {
            newText.append(" ");
        }
        return newText.toString();
    }

    // Format and set the text in the text field.  The oldText corresponds
    // to the former values of the registers, and the curText corresponds
    // to the current values of the registers.
    public String setAndFormatText( String oldText, String curText ) {
        int curTextLength = curText.length();
        int curLastNewLinePos = -1;
        int curStartIndex = 0;
        int oldTextLength = oldText.length();
        int oldLastNewLinePos = -1;
        int oldStartIndex = 0;

        boolean printNewLineFlag = false;
        String newText = new String();
        int entriesOnThisLine = 0;

        comArea.setText( "" );

        while ( curStartIndex < curTextLength ) {
            String curLineOfText;
            String oldLineOfText;
            int curLineLength = 0;
            int oldLineLength = 0;

            curLastNewLinePos = curText.indexOf('\n', curStartIndex);
            oldLastNewLinePos = oldText.indexOf('\n', curStartIndex);
            if (curLastNewLinePos == -1) {
                curLineOfText = curText.substring(curStartIndex);
                oldLineOfText = oldText.substring(oldStartIndex);
                curLineLength = curLineOfText.length();
                oldLineLength = oldLineOfText.length();
            }
            else if (curLastNewLinePos == curStartIndex) {
                curLineOfText = "";
                oldLineOfText = "";
                curLineLength = 0;
                oldLineLength = 0;
            }
            else {
                curLineOfText =
                    curText.substring(curStartIndex, curLastNewLinePos);
                oldLineOfText =
                    oldText.substring(oldStartIndex, oldLastNewLinePos);
                curLineLength = curLineOfText.length();
                oldLineLength = oldLineOfText.length();
            }

            // If the lines are equal, then there has been no change
            // in the register value so we don't highlight it;
            // otherwise, highlight the register values.
            if (oldLineOfText.equals(curLineOfText)) {
                comArea.append(
                    formatText( curLineLength, curLineOfText,false) );
            }
            else {
                comArea.append(
                    formatText( curLineLength,curLineOfText,true) );
            }

            // Determine if we should insert a newline
            entriesOnThisLine++;
            if ( entriesOnThisLine >= ENTRIES_PER_LINE ) {
                comArea.append("\n");
                entriesOnThisLine = 0;
            }

            // Update the starting indices
            curStartIndex = curLastNewLinePos + 1;
            oldStartIndex = oldLastNewLinePos + 1;
        }
        return newText;
    }
}
