//*****************************************************************************
/*
** FILE:   eh_DebugListModel.java
**
** (c) 1998 Steve Withall.
**
** HISTORY:
**    25Apr98  stevew  Created, split from eh_Debug.
*/
package eh;

import com.sun.java.swing.text.BadLocationException;
import com.sun.java.swing.text.PlainDocument;

//*****************************************************************************
/**
 * <p>eh_DebugListModel manages the buffering of lines of debug output in order
 * to display them without a significant performance overhead. Debug output is
 * placed in a StringBuffer, which is then added to a PlainDocument that drives
 * the display itself. The StringBuffer and PlainDocument live herein.</p>
 */
public class eh_DebugListModel
{
    protected StringBuffer   DebugBuffer      = new StringBuffer(20000);
    /** Area for storing a number of debug lines before displaying them. */

    // Attributes relating to on-screen display of debug information.
	/** Document into which debug information is to be placed for display. */
    protected PlainDocument  DebugDocument    = new PlainDocument();

	/** The maximum number of characters the debug box will hold.
	 *  Once this limit is reached, a chunk is removed from the front. */
	protected int            DebugBoxMaxChars = 20000;

	/** Once the debug box has reached its maximum size, this number of characters
	 *  will be trimmed from its start. */
	protected int            DebugBoxTrimSize = 2000;

    //*****************************************************************************
    /**
     * Add InputString to debug output.
     *
     * @param  InputString  The string to output
     */
	public void add(String  InputString)
    {
        synchronized (DebugBuffer)
        {
            DebugBuffer.append('\n');
            DebugBuffer.append(InputString);
        }
    }

    //*****************************************************************************
	/**
	 * Move the buffered output to the screen.
	 */
    protected void refreshScreen()
    {
        synchronized (DebugBuffer)
        {
            synchronized (DebugDocument)
            {
                int  DocumentLength = 0;
                int  EndOffset      = 0;
                try
                {
                    DocumentLength = DebugDocument.getLength();
                    EndOffset      = DebugDocument.getEndPosition().getOffset();
//    	            System.err.println("eh_DebugListModel.refreshScreen: insertString"
//    	                                     + "; end offset = " + EndOffset
//    	                                     + "; length = " + DocumentLength);
                    DebugDocument.insertString(DebugDocument.getLength(),
                                               DebugBuffer.toString(),
                                               null);
                }
    	        catch (BadLocationException InputException)
    	        {
    	            System.err.println("eh_DebugListModel.refreshScreen: unable to get position in debug document: "
    	                                     + InputException + "; end offset = " + EndOffset
    	                                     + "; length = " + DocumentLength);
    	        }

                DebugBuffer = new StringBuffer(DebugBoxMaxChars);  // Empty the buffer

    	        checkCapacity();
    	    }
        }
	    return;
    }

    //*****************************************************************************
	/**
	 * If the debug box has reached its designated capacity, trim it by removing a
	 * chunk from the beginning. The size of the chunk to remove is such that we
	 * end up with 10% less than capacity.
	 */
	protected void  checkCapacity()
	{
        synchronized (DebugDocument)
        {
    	    int  EndOffset = DebugDocument.getLength();
//    	    System.err.println("eh_DebugListModel.checkCapacity: length = " + EndOffset
//    	                             + "; capacity = " + DebugBoxMaxChars);
	        if (EndOffset > DebugBoxMaxChars)
	        {
                try
                {
//    	            System.err.println("eh_DebugListModel.checkCapacity: remove "
//    	                                     + (EndOffset - DebugBoxMaxChars + DebugBoxTrimSize) );
                    DebugDocument.remove(DebugDocument.getStartPosition().getOffset(),
                                         (EndOffset - DebugBoxMaxChars + DebugBoxTrimSize) );
                    //TBD Clip the remainder of the current first line.
                }
    	        catch (BadLocationException InputException)
    	        {
    	            System.err.println("eh_DebugListModel.checkCapacity is unable to get position in debug document:"
    	                                     + InputException);
    	        }
    	    }
		}

	    return;
	}

    //*****************************************************************************
    // Attribute setting functions.
    //*****************************************************************************
/*	public void  setDebugDocument(PlainDocument  InputDebugDocument)
	{
        DebugDocument = InputDebugDocument;
	}
*/
    //*****************************************************************************
	public void  setDebugBoxMaxChars(int  InputMaxLines)
	{
	    DebugBoxMaxChars = InputMaxLines;
	    DebugBoxTrimSize = (int)(InputMaxLines * 0.1);
	}

    //*****************************************************************************
    // Attribute retrieval functions.
    //*****************************************************************************
    public PlainDocument getDebugDocument()
    {
	    return DebugDocument;
    }

    //*****************************************************************************
    public int getDebugBoxMaxChars()
    {
	    return DebugBoxMaxChars;
    }
}

//*****************************************************************************
