/*
 *******************************************************************************
 * Copyright (C) 1996-2003, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/impl/DumbTextComponent.java,v $ 
 * $Date: 2003/06/03 18:49:27 $ 
 * $Revision: 1.8 $
 *
 *****************************************************************************************
 */
package com.ibm.icu.dev.demo.impl;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.awt.datatransfer.*;

// LIU: Changed from final to non-final
public class DumbTextComponent extends Canvas
  implements KeyListener, MouseListener, MouseMotionListener, FocusListener
  {
    private transient static final String copyright =
      "Copyright \u00A9 1998, Mark Davis. All Rights Reserved.";
    private transient static boolean DEBUG = false;

    private String contents = "";
    private Selection selection = new Selection();
    private int activeStart = -1;
    private boolean editable = true;

    private transient Selection tempSelection = new Selection();
    private transient boolean focus;
    private transient BreakIterator lineBreaker = BreakIterator.getLineInstance();
    private transient BreakIterator wordBreaker = BreakIterator.getWordInstance();
    private transient BreakIterator charBreaker = BreakIterator.getCharacterInstance();
    private transient int lineAscent;
    private transient int lineHeight;
    private transient int lineLeading;
    private transient int lastHeight = 10;
    private transient int lastWidth = 50;
    private static final int MAX_LINES = 200; // LIU: Use symbolic name
    private transient int[] lineStarts = new int[MAX_LINES]; // LIU
    private transient int lineCount = 1;

    private transient boolean valid = false;
    private transient FontMetrics fm;
    private transient boolean redoLines = true;
    private transient boolean doubleClick = false;
    private transient TextListener textListener;
    private transient ActionListener selectionListener;
    private transient Image cacheImage;
    private transient Dimension mySize;
    private transient int xInset = 5;
    private transient int yInset = 5;
    private transient Point startPoint = new Point();
    private transient Point endPoint = new Point();
    private transient Point caretPoint = new Point();
    private transient Point activePoint = new Point();
    
    //private transient static String clipBoard;

    private static final char CR = '\015'; // LIU

    // ============================================

    public DumbTextComponent() {
        addMouseListener(this);
        addMouseMotionListener(this);
        addKeyListener(this);
        addFocusListener(this);
        setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));

    }

// ================ Events ====================

    // public boolean isFocusTraversable() { return true; }

	public void addActionListener(ActionListener l) {
        selectionListener = AWTEventMulticaster.add(selectionListener, l);
	}

	public void removeActionListener(ActionListener l) {
        selectionListener = AWTEventMulticaster.remove(selectionListener, l);
	}

	public void addTextListener(TextListener l) {
        textListener = AWTEventMulticaster.add(textListener, l);
	}

	public void removeTextListener(TextListener l) {
        textListener = AWTEventMulticaster.remove(textListener, l);
	}

    private transient boolean pressed;

	public void mousePressed(MouseEvent e) {
	    if (DEBUG) System.out.println("mousePressed");
	    if (pressed) {
	        select(e,false);
	    } else {
            doubleClick = e.getClickCount() > 1;
            requestFocus();
            select(e, true);
    	    pressed = true;
	    }
	}

	public void mouseDragged(MouseEvent e) {
	    if (DEBUG) System.out.println("mouseDragged");
	    select(e, false);
	}

	public void mouseReleased(MouseEvent e) {
	    if (DEBUG) System.out.println("mouseReleased");
	    pressed = false;
	}

	public void mouseEntered(MouseEvent e) {
	    //if (pressed) select(e, false);
	}

	public void mouseExited(MouseEvent e){
	    //if (pressed) select(e, false);
	}

	public void mouseClicked(MouseEvent e) {}
	public void mouseMoved(MouseEvent e) {}


    public void focusGained(FocusEvent e) {
	    if (DEBUG) System.out.println("focusGained");
	    focus = true;
	    valid = false;
	    repaint(16);
	}
	public void focusLost(FocusEvent e) {
	    if (DEBUG) System.out.println("focusLost");
	    focus = false;
	    valid = false;
	    repaint(16);
	}

    public void select(MouseEvent e, boolean first) {
        setKeyStart(-1);
	    point2Offset(e.getPoint(), tempSelection);
        if (first) {
            if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
                tempSelection.anchor = tempSelection.caret;
            }
	    }
	    // fix words
	    if (doubleClick) {
	        tempSelection.expand(wordBreaker);
	    }
	    select(tempSelection);
    }
    
	public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (DEBUG) System.out.println("keyPressed "
          + hex((char)code) + ", " + hex((char)e.getModifiers()));
        int start = selection.getStart();
        int end = selection.getEnd();
        boolean shift = (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0;
        boolean ctrl = (e.getModifiers() & KeyEvent.CTRL_MASK) != 0;
                
        switch (code) {
        case KeyEvent.VK_Q:
            if (!ctrl || !editable) break;
            setKeyStart(-1);
            fixHex();
            break;
        case KeyEvent.VK_V:
            if (!ctrl) break;
            if (!editable) {
                this.getToolkit().beep();
            } else {
                paste();
            }
            break;
        case KeyEvent.VK_C:
            if (!ctrl) break;
            copy();
            break;
        case KeyEvent.VK_X:
            if (!ctrl) break;
            if (!editable) {
                this.getToolkit().beep();
            } else {
                copy();
                insertText("");
            }
            break;
        case KeyEvent.VK_A:
            if (!ctrl) break;
            setKeyStart(-1);
            select(Integer.MAX_VALUE, 0, false);
            break;
        case KeyEvent.VK_RIGHT:
            setKeyStart(-1);
            tempSelection.set(selection);
            tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, +1, shift);
            select(tempSelection);
            break;
        case KeyEvent.VK_LEFT:
            setKeyStart(-1);
            tempSelection.set(selection);
            tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, -1, shift);
            select(tempSelection);
            break;
        case KeyEvent.VK_UP: // LIU: Add support for up arrow
            setKeyStart(-1);
            tempSelection.set(selection);
            tempSelection.caret = lineDelta(tempSelection.caret, -1);
            if (!shift) {
                tempSelection.anchor = tempSelection.caret;
            }
            select(tempSelection);
            break;
        case KeyEvent.VK_DOWN: // LIU: Add support for down arrow
            setKeyStart(-1);
            tempSelection.set(selection);
            tempSelection.caret = lineDelta(tempSelection.caret, +1);
            if (!shift) {
                tempSelection.anchor = tempSelection.caret;
            }
            select(tempSelection);
            break;
        case KeyEvent.VK_DELETE: // LIU: Add delete key support
            if (!editable) break;
            setKeyStart(-1);
            if (contents.length() == 0) break;
            start = selection.getStart();
            end = selection.getEnd();
            if (start == end) {
                ++end;
                if (end > contents.length()) {
                    getToolkit().beep();
                    return;
                }
            }
            replaceRange("", start, end);
            break;            
        }
    }

    void copy() {
        Clipboard cb = this.getToolkit().getSystemClipboard();
        StringSelection ss = new StringSelection(
            contents.substring(selection.getStart(), selection.getEnd()));
        cb.setContents(ss, ss);
    }
    
    void paste () {
        Clipboard cb = this.getToolkit().getSystemClipboard();
        Transferable t = cb.getContents(this);
        if (t == null) {
            this.getToolkit().beep();
            return;
        }
        try {
            String temp = (String) t.getTransferData(DataFlavor.stringFlavor);
            insertText(temp);
        } catch (Exception e) {
            this.getToolkit().beep();
        }            
    }

    /**
     * LIU: Given an offset into contents, moves up or down by lines,
     * according to lineStarts[].
     * @param off the offset into contents
     * @param delta how many lines to move up (< 0) or down (> 0)
     * @return the new offset into contents
     */
    private int lineDelta(int off, int delta) {
        int line = findLine(off, false);
        int posInLine = off - lineStarts[line];
        // System.out.println("off=" + off + " at " + line + ":" + posInLine);
        line += delta;
        if (line < 0) {
            line = posInLine = 0;
        } else if (line >= lineCount) {
            return contents.length();
        }
        off = lineStarts[line] + posInLine;
        if (off >= lineStarts[line+1]) {
            off = lineStarts[line+1] - 1;
        }
        return off;
    }
      
	public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();
        if (DEBUG) System.out.println("keyReleased "
          + hex((char)code) + ", " + hex((char)e.getModifiers()));
    }

	public void keyTyped(KeyEvent e) {
        char ch = e.getKeyChar();
        if (DEBUG) System.out.println("keyTyped "
          + hex((char)ch) + ", " + hex((char)e.getModifiers()));
        if ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0) return;
        int start, end;
        switch (ch) {
        case KeyEvent.CHAR_UNDEFINED:
            break;
        case KeyEvent.VK_BACK_SPACE:
            //setKeyStart(-1);
            if (!editable) break;
            if (contents.length() == 0) break;
            start = selection.getStart();
            end = selection.getEnd();
            if (start == end) {
                --start;
                if (start < 0) {
                    getToolkit().beep(); // LIU: Add audio feedback of NOP
                    return;
                }
            }
            replaceRange("", start, end);
            break;        
        case KeyEvent.VK_DELETE:
            //setKeyStart(-1);
            if (!editable) break;
            if (contents.length() == 0) break;
            start = selection.getStart();
            end = selection.getEnd();
            if (start == end) {
                ++end;
                if (end > contents.length()) {
                    getToolkit().beep(); // LIU: Add audio feedback of NOP
                    return;
                }
            }
            replaceRange("", start, end);
            break;
        default:
            if (!editable) break;
            // LIU: Dispatch to subclass API
            handleKeyTyped(e);
            break;
        }
    }

    // LIU: Subclass API for handling of key typing
    protected void handleKeyTyped(KeyEvent e) {
        insertText(String.valueOf(e.getKeyChar()));
    }
    
    protected void setKeyStart(int keyStart) {
        if (activeStart != keyStart) {
            activeStart = keyStart;
            repaint(10);
        }
    }
    
    protected void validateKeyStart() {
    	if (activeStart > selection.getStart()) {
            activeStart = selection.getStart();
            repaint(10);
        }
    }
    
    protected int getKeyStart() {
        return activeStart;
    }

// ===================== Control ======================

    public synchronized void setEditable(boolean b) {
        editable = b;
    }

    public boolean isEditable() {
        return editable;
    }

    public void select(Selection newSelection) {
        newSelection.pin(contents);
        if (!selection.equals(newSelection)) {
            selection.set(newSelection);
            if (selectionListener != null) {
                selectionListener.actionPerformed(
                  new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
                    "Selection Changed", 0));
            }
            repaint(10);
            valid = false;
        }
    }

    public void select(int start, int end) {
        select(start, end, false);
    }

    public void select(int start, int end, boolean clickAfter) {
        tempSelection.set(start, end, clickAfter);
        select(tempSelection);
    }

    public int getSelectionStart() {
        return selection.getStart();
    }

    public int getSelectionEnd() {
        return selection.getEnd();
    }

    public void setBounds(int x, int y, int w, int h) {
        super.setBounds(x,y,w,h);
        redoLines = true;
    }

    public Dimension getPreferredSize() {
        return new Dimension(lastWidth,lastHeight);
    }

    public Dimension getMaximumSize() {
        return new Dimension(lastWidth,lastHeight);
    }

    public Dimension getMinimumSize() {
        return new Dimension(lastHeight,lastHeight);
    }

    public void setText(String text) {
        setText2(text);
        select(tempSelection.set(selection).pin(contents));
    }

    public void setText2(String text) {
        contents = text;
        charBreaker.setText(text);
        wordBreaker.setText(text);
        lineBreaker.setText(text);
        redoLines = true;
        if (textListener != null)
            textListener.textValueChanged(
              new TextEvent(this, TextEvent.TEXT_VALUE_CHANGED));
        repaint(16);
    }

    public void insertText(String text) {
        if (activeStart == -1) activeStart = selection.getStart();
        replaceRange(text, selection.getStart(), selection.getEnd());
    }

    public void replaceRange(String s, int start, int end) {
        setText2(contents.substring(0,start) + s
          + contents.substring(end));
        select(tempSelection.set(selection).
          fixAfterReplace(start, end, s.length()));
        validateKeyStart();
    }

    public String getText() {
        return contents;
    }

    public void setFont(Font font) {
        super.setFont(font);
        redoLines = true;
        repaint(16);
    }

    // ================== Graphics ======================

    public void update(Graphics g) {
        if (DEBUG) System.out.println("update");
        paint(g);
    }

    public void paint(Graphics g) {
        mySize = getSize();
        if (cacheImage == null
          || cacheImage.getHeight(this) != mySize.height
          || cacheImage.getWidth(this) != mySize.width) {
            cacheImage = createImage(mySize.width, mySize.height);
            valid = false;
        }
        if (!valid || redoLines) {
            if (DEBUG) System.out.println("painting");
            paint2(cacheImage.getGraphics());
            valid = true;
        }
        //getToolkit().sync();
        if (DEBUG) System.out.println("copying");
        g.drawImage(cacheImage,
          0, 0, mySize.width, mySize.height,
          0, 0, mySize.width, mySize.height,
          this);
    }

    public void paint2(Graphics g) {
        g.clearRect(0, 0, mySize.width, mySize.height);
        if (DEBUG) System.out.println("print");
        if (focus) g.setColor(Color.black);
        else g.setColor(Color.gray);
        g.drawRect(0,0,mySize.width-1,mySize.height-1);
        g.setClip(1,1,
          mySize.width-2,mySize.height-2);
        g.setColor(Color.black);
        g.setFont(getFont());
        fm = g.getFontMetrics();
        lineAscent = fm.getAscent();
        lineLeading = fm.getLeading();
        lineHeight = lineAscent + fm.getDescent() + lineLeading;
        int y = yInset + lineAscent;
        String lastSubstring = "";
        if (redoLines) fixLineStarts(mySize.width-xInset-xInset);
        for (int i = 0; i < lineCount; y += lineHeight, ++i) {
            // LIU: Don't display terminating ^M characters
            int lim = lineStarts[i+1];
            if (lim > 0 && contents.length() > 0 &&
                contents.charAt(lim-1) == CR) --lim;
            lastSubstring = contents.substring(lineStarts[i],lim);
            g.drawString(lastSubstring, xInset, y);
        }
        drawSelection(g, lastSubstring);
        lastHeight = y + yInset - lineHeight + yInset;
        lastWidth = mySize.width-xInset-xInset;
    }

    void paintRect(Graphics g, int x, int y, int w, int h) {
        if (focus) {
            g.fillRect(x, y, w, h);
        } else {
            g.drawRect(x, y, w-1, h-1);
        }
    }

    public void drawSelection(Graphics g, String lastSubstring) {
        g.setXORMode(Color.black);
        if (activeStart != -1) {
            offset2Point(activeStart, false, activePoint);
            g.setColor(Color.magenta);
            int line = activePoint.x - 1;
            g.fillRect(line, activePoint.y, 1, lineHeight);
        }
        if (selection.isCaret()) {
            offset2Point(selection.caret, selection.clickAfter, caretPoint);
        } else {
            if (focus) g.setColor(Color.blue);
            else g.setColor(Color.yellow);
            offset2Point(selection.getStart(), true, startPoint);
            offset2Point(selection.getEnd(), false, endPoint);
            if (selection.getStart() == selection.caret)
                caretPoint.setLocation(startPoint);
            else caretPoint.setLocation(endPoint);
            if (startPoint.y == endPoint.y) {
                paintRect(g, startPoint.x, startPoint.y,
                  Math.max(1,endPoint.x-startPoint.x), lineHeight);
            } else {
                paintRect(g, startPoint.x, startPoint.y,
                  (mySize.width-xInset)-startPoint.x, lineHeight);
                if (startPoint.y + lineHeight < endPoint.y)
                  paintRect(g, xInset, startPoint.y + lineHeight,
                  (mySize.width-xInset)-xInset, endPoint.y - startPoint.y - lineHeight);
                paintRect(g, xInset, endPoint.y, endPoint.x-xInset, lineHeight);
            }
        }
        if (focus || selection.isCaret()) {
            if (focus) g.setColor(Color.green);
            else g.setColor(Color.red);
            int line = caretPoint.x - (selection.clickAfter ? 0 : 1);
            g.fillRect(line, caretPoint.y, 1, lineHeight);
            int w = lineHeight/12 + 1;
            int braces = line - (selection.clickAfter ? -1 : w);
            g.fillRect(braces, caretPoint.y, w, 1);
            g.fillRect(braces, caretPoint.y + lineHeight - 1, w, 1);
        }
    }

    public Point offset2Point(int off, boolean start, Point p) {
        int line = findLine(off, start);
        int width = 0;
        try {
            width = fm.stringWidth(
              contents.substring(lineStarts[line], off));
        } catch (Exception e) {
            System.out.println(e);
        }
        p.x = width + xInset;
        if (p.x > mySize.width - xInset)
            p.x = mySize.width - xInset;
        p.y = lineHeight * line + yInset;
        return p;
    }

    private int findLine(int off, boolean start) {
        // if it is start, then go to the next line!
        if (start) ++off;
        for (int i = 1; i < lineCount; ++i) {
            // LIU: This was <= ; changed to < to make caret after
            // final CR in line appear at START of next line.
            if (off < lineStarts[i]) return i-1;
        }
        // LIU: Check for special case; after CR at end of the last line
        if (off == lineStarts[lineCount] &&
            off > 0 && contents.length() > 0 && contents.charAt(off-1) == CR) {
            return lineCount;
        }
        return lineCount-1;
    }

    // offsets on any line will go from start,true to end,false
    // excluding start,false and end,true
    public Selection point2Offset(Point p, Selection o) {
        if (p.y < yInset) {
            o.caret = 0;
            o.clickAfter = true;
            return o;
        }
        int line = (p.y - yInset)/lineHeight;
        if (line >= lineCount) {
            o.caret = contents.length();
            o.clickAfter = false;
            return o;
        }
        int target = p.x - xInset;
        if (target <= 0) {
            o.caret = lineStarts[line];
            o.clickAfter = true;
            return o;
        }
        int lowGuess = lineStarts[line];
        int lowWidth = 0;
        int highGuess = lineStarts[line+1];
        int highWidth = fm.stringWidth(contents.substring(lineStarts[line],highGuess));
        if (target >= highWidth) {
            o.caret = lineStarts[line+1];
            o.clickAfter = false;
            return o;
        }
        while (lowGuess < highGuess - 1) {
            int guess = (lowGuess + highGuess)/2;
            int width = fm.stringWidth(contents.substring(lineStarts[line],guess));
            if (width <= target) {
                lowGuess = guess;
                lowWidth = width;
                if (width == target) break;
            } else {
                highGuess = guess;
                highWidth = width;
            }
        }
        // at end, either lowWidth < target < width(low+1), or lowWidth = target
        int highBound = charBreaker.following(lowGuess);
        int lowBound = charBreaker.previous();
        // we are now at character boundaries
        if (lowBound != lowGuess)
            lowWidth = fm.stringWidth(contents.substring(lineStarts[line],lowBound));
        if (highBound != highGuess)
            highWidth = fm.stringWidth(contents.substring(lineStarts[line],highBound));
        // we now have the right widths
        if (target - lowWidth < highWidth - target) {
            o.caret = lowBound;
            o.clickAfter = true;
        } else {
            o.caret = highBound;
            o.clickAfter = false;
        }
        // we now have the closest!
        return o;
    }

    private void fixLineStarts(int width) {
        lineCount = 1;
        lineStarts[0] = 0;
        if (contents.length() == 0) {
            lineStarts[1] = 0;
            return;
        }
        int end = 0;
        // LIU: Add check for MAX_LINES
        for (int start = 0; start < contents.length() && lineCount < MAX_LINES;
             start = end) {
            end = nextLine(fm, start, width);
            lineStarts[lineCount++] = end;
            if (end == start) { // LIU: Assertion
                throw new RuntimeException("nextLine broken");
            }
        }
        --lineCount;
        redoLines = false;
    }

    // LIU: Enhanced to wrap long lines.  Bug with return of start fixed.
    public int nextLine(FontMetrics fm, int start, int width) {
        int len = contents.length();
        for (int i = start; i < len; ++i) {
            // check for line separator
            char ch = (contents.charAt(i));
            if (ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029) {
                len = i + 1;
                if (ch == 0x000D && i+1 < len && contents.charAt(i+1) == 0x000A) // crlf
                    ++len; // grab extra char
                break;
            }
        }
        String subject = contents.substring(start,len);
        if (visibleWidth(fm, subject) <= width)
          return len;

        // LIU: Remainder of this method rewritten to accomodate lines
        // longer than the component width by first trying to break
        // into lines; then words; finally chars.
        int n = findFittingBreak(fm, subject, width, lineBreaker);
        if (n == 0) {
            n = findFittingBreak(fm, subject, width, wordBreaker);
        }
        if (n == 0) {
            n = findFittingBreak(fm, subject, width, charBreaker);
        }
        return n > 0 ? start + n : len;
    }

    /**
     * LIU: Finds the longest substring that fits a given width
     * composed of subunits returned by a BreakIterator.  If the smallest
     * subunit is too long, returns 0.
     * @param fm metrics to use
     * @param line the string to be fix into width
     * @param width line.substring(0, result) must be <= width
     * @param breaker the BreakIterator that will be used to find subunits
     * @return maximum characters, at boundaries returned by breaker,
     * that fit into width, or zero on failure
     */
    private int findFittingBreak(FontMetrics fm, String line, int width,
                                 BreakIterator breaker) {
        breaker.setText(line);
        int last = breaker.first();
        int end = breaker.next();
        while (end != BreakIterator.DONE &&
               visibleWidth(fm, line.substring(0, end)) <= width) {
            last = end;
            end = breaker.next();
        }
        return last;
    }

    public int visibleWidth(FontMetrics fm, String s) {
        int i;
        for (i = s.length()-1; i >= 0; --i) {
            char ch = s.charAt(i);
            if (!(ch == ' ' || ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029))
              return fm.stringWidth(s.substring(0,i+1));;
        }
        return 0;
    }

// =============== Utility ====================

    private void fixHex() {
        if (selection.getEnd() == 0) return;
        int store = 0;
        int places = 1;
        int count = 0;
        int min = Math.min(8,selection.getEnd());
        for (int i = 0; i < min; ++i) {
            char ch = contents.charAt(selection.getEnd()-1-i);
            int value = Character.getNumericValue(ch);
            if (value < 0 || value > 15) break;
            store += places * value;
            ++count;
            places *= 16;
        }
        String add = "";
        int bottom = store & 0xFFFF;
        if (store >= 0xD8000000 && store < 0xDC000000
          && bottom >= 0xDC00 && bottom < 0xE000) { // surrogates
            add = "" + (char)(store >> 16) + (char)bottom;
        } else if (store > 0xFFFF && store <= 0x10FFFF) {
            store -= 0x10000;
            add = "" + (char)(((store >> 10) & 0x3FF) + 0xD800)
              + (char)((store & 0x3FF) + 0xDC00);
              
        } else if (count >= 4) {
            count = 4;
            add = ""+(char)(store & 0xFFFF);
        } else {
            count = 1;
            char ch = contents.charAt(selection.getEnd()-1);
            add = hex(ch);
            if (ch >= 0xDC00 && ch <= 0xDFFF && selection.getEnd() > 1) {
                ch = contents.charAt(selection.getEnd()-2);
                if (ch >= 0xD800 && ch <= 0xDBFF) {
                    count = 2;
                    add = hex(ch) + add;
                }
            }
        }
        replaceRange(add, selection.getEnd()-count, selection.getEnd());
    }

    public static String hex(char ch) {
        String result = Integer.toString(ch,16).toUpperCase();
        result = "0000".substring(result.length(),4) + result;
        return result;
    }
}
