/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 22-Dec-2004
 *
 */
package uk.ac.ic.doc.kevlar.gui.internal.widgets.textbox;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;

import uk.ac.ic.doc.kevlar.gui.internal.AMouseListenerObject;
import uk.ac.ic.doc.kevlar.gui.internal.caches.ColorCache;
import uk.ac.ic.doc.kevlar.gui.internal.caches.FontCache;
import uk.ac.ic.doc.kevlar.gui.internal.caches.Utils;
import uk.ac.ic.doc.kevlar.gui.internal.keyboard.KeyboardManager;
import uk.ac.ic.doc.kevlar.gui.internal.keyboard.states.MultilineTextBoxState;
import uk.ac.ic.doc.kevlar.publicUtil.strings.StringUtil;

/**
 * @author Marc
 **/
public class TextArea extends AMouseListenerObject implements ClipboardOwner {

    protected MultilineTextBox parent;
    protected String text;
    protected ArrayList<String> lines;
    protected ArrayList<Boolean> forcedReturn;
    protected GC evilHack;
    protected Font font;
    protected int fontHeight;
    protected Point caretPos;
    protected Caret caret;
    protected boolean selecting;
    protected Point selectionStart;
    protected Point selectionEnd;
    protected boolean editable;
    
    public TextArea(MultilineTextBox parent) {
        
        super();

        this.parent = parent;
        
		font = FontCache.get("Courier New", 10, SWT.NORMAL);
        evilHack = new GC(new Image(Display.getDefault(), 1, 1));
        evilHack.setFont(font);
        fontHeight = evilHack.textExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ").y;
        
        text = "";
        lines = new ArrayList<String>();
        forcedReturn = new ArrayList<Boolean>();
        selecting = false;
        selectionStart = new Point(0, 0);
        selectionEnd = new Point(0, 0);
        editable = true;
        
        caretPos = new Point(0, 0);
        
        caret = new Caret();
        caret.setSize(new Point(1, fontHeight));
        caret.permanentlyHide();
        addChild(caret);
                
    }

    public void setEditable(boolean editable) {
        
        this.editable = editable;
        
    }
    
    public void setText(String text) {
        
        this.text = text;
        
        selectionStart = new Point(0, 0);
        selectionEnd = new Point(0, 0);
        selecting = false;
        
        updateLines();        
        redraw();
        
    }
    
    public String getText() {
        
        return text;
        
    }
    
    public int linedPosToNonLinedPos(Point linedPos) {
        
        if (linedPos.y < 0) {
            
            return 0;
            
        } else if (linedPos.y >= lines.size()) {
            
            return text.length();
            
        } else {
            
            int result = 0;
            
            for (int i=0; i<linedPos.y; i++) {
                
                result += lines.get(i).length();
                
                if (forcedReturn.get(i).booleanValue()) {
                    
                    result += StringUtil.NEWLINE.length();
                    
                }
                
            }
            
            String line = lines.get(linedPos.y);
            
            if (linedPos.x < 0) {
                
                return result;
                
            } else if (linedPos.x > line.length()) {
                
                return result+line.length();
                
            } else {
            
                return result+linedPos.x;
                
            }
            
        }
        
    }
    
    public Point nonLinedPosToLinedPos(int nonLinedPos) {
        
        Point result = new Point(0, 0);
        
        while (result.y < lines.size()) {
            
            String line = lines.get(result.y);
            int lineLength = line.length();
            
            if (forcedReturn.get(result.y).booleanValue()) {
                
                lineLength += StringUtil.NEWLINE.length();
                
            }
            
            if (nonLinedPos < lineLength) {
                
                result.x = nonLinedPos;
                return result;
                
            } else {
                
                result.y++;
                nonLinedPos -= lineLength;
                
            }
            
        }
        
        return result;
        
    }
    
    public void home() {
        
        if (lines.size() <= 0 || caretPos.y < 0) {
            
            setCaretPos(new Point(0, 0));
            
        } else if (caretPos.y >= lines.size()) {
            
            setCaretPos(new Point(0, lines.size()-1));
            
        } else {
            
            setCaretPos(new Point(0, caretPos.y));
            
        }
        
        redraw();
        
    }
    
    public void end() {
        
        if (lines.size() <= 0 || caretPos.y < 0) {
            
            setCaretPos(new Point(0, 0));
            
        } else if (caretPos.y >= lines.size()) {
            
            setCaretPos(new Point(lines.get(lines.size()-1).length(), lines.size()-1));
            
        } else {
            
            setCaretPos(new Point(lines.get(caretPos.y).length(), caretPos.y));
            
        }
        
        redraw();
        
    }
        
    public void ctrlHome() {
        
        setCaretPos(new Point(0, 0));
        redraw();
        
    }
    
    public void ctrlEnd() {
        
        if (lines.size() <= 0) {
            
            setCaretPos(new Point(0, 0));
            
        } else {
            
            setCaretPos(new Point(lines.get(lines.size()-1).length(), lines.size()-1));
            
        }
        
        redraw();
        
    }
    
    public void insert(char c) {
        
        if (editable) {
        
            if (!equal(selectionStart, selectionEnd)) {
                
                delete();
                
            } 
            
            int nonLinedPos = linedPosToNonLinedPos(caretPos);
            setText(text.substring(0,nonLinedPos)+c+text.substring(nonLinedPos));
            
            setCaretPos(nonLinedPosToLinedPos(nonLinedPos+1));
            redraw();
            
        }
        
    }
        
    public void insert(String s) {
        
        if (editable) {
        
            if (!equal(selectionStart, selectionEnd)) {
                
                delete();
                
            } 
            
            int nonLinedPos = linedPosToNonLinedPos(caretPos);
            setText(text.substring(0,nonLinedPos)+s+text.substring(nonLinedPos));
            
            setCaretPos(nonLinedPosToLinedPos(nonLinedPos+s.length()));
            redraw();
            
        }
        
    }
        
    public void append(String s) {
        
        text = text+StringUtil.NEWLINE+s;
        appendLines(s);
        redraw();
        
    }
    
    public void delete() {
        
        if (editable) {
        
            if (!equal(selectionStart, selectionEnd)) {
                
                selecting = false;
                int temp;
                
                if (lessThan(selectionStart, selectionEnd)) {
                    
                    int start = linedPosToNonLinedPos(selectionStart);
                    int end = linedPosToNonLinedPos(selectionEnd);
                    temp = start;
                    setText(text.substring(0, start)+text.substring(end));
                    
                } else {
                    
                    int start = linedPosToNonLinedPos(selectionStart);
                    int end = linedPosToNonLinedPos(selectionEnd);
                    temp = end;
                    setText(text.substring(0, end)+text.substring(start));
                    
                }
                
                setCaretPos(nonLinedPosToLinedPos(temp));
                selectionStart = new Point(0, 0);
                selectionEnd = new Point(0, 0);
                
            } else {
                
                int pos = linedPosToNonLinedPos(caretPos);
                
                if (pos < text.length()) {
                    
                    setText(text.substring(0, pos)+text.substring(pos+1));
                    setCaretPos(nonLinedPosToLinedPos(pos));
                    
                }
                
            }
            
        }
        
    }
      
    public void backSpace() {
        
        if (editable) {
        
            if (!equal(selectionStart, selectionEnd)) {
                
                delete();
                
            } else {
                
                int pos = linedPosToNonLinedPos(caretPos);
                
                if (pos > 0) {
                    
                    setCaretPos(nonLinedPosToLinedPos(pos-1));
                    delete();
                    
                }
                
            }
            
        }
        
    }
       
    public void cut() {
        
        if (!equal(selectionStart, selectionEnd)) {
        
            copy();
            delete();
            
        }
        
    }
    
    public void copy() {
        
        if (!equal(selectionStart, selectionEnd)) {
            
            Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
            
            if (lessThan(selectionStart, selectionEnd)) {
                
                int start = linedPosToNonLinedPos(selectionStart);
                int end = linedPosToNonLinedPos(selectionEnd);
                c.setContents(new StringSelection(text.substring(start, end)), this);
                
            } else {
                
                int start = linedPosToNonLinedPos(selectionEnd);
                int end = linedPosToNonLinedPos(selectionStart);
                c.setContents(new StringSelection(text.substring(start, end)), this);
                
            }
                            
        }
        
    }
    
    public void paste() {
        
        try {
        
            Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
            
            if (c.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
            
                insert((String)c.getData(DataFlavor.stringFlavor));
                
            }
            
        } catch(UnsupportedFlavorException e) {
            
            System.err.println("Unsupported flavor: "+e);
            
        } catch (IOException e) {
            
            System.err.println("IO Exception: "+e);
            
        }
        
    }
        
    public Caret getCaret() {
        
        return caret;
        
    }
    
    public void moveCaretUp() {
        
        setCaretPos(new Point(caretPos.x, caretPos.y-1));
        redraw();
        
    }
    
    public void moveCaretDown() {
        
        setCaretPos(new Point(caretPos.x, caretPos.y+1));
        redraw();
        
    }
        
    public void moveCaretLeft() {
        
        if (caretPos.x == 0) {

            if (caretPos.y > 0 && lines.size() > caretPos.y-1) {
                
                setCaretPos(new Point(lines.get(caretPos.y-1).length(), caretPos.y-1));
                
            } else {
                
                setCaretPos(new Point(0, 0));
                
            }
            
        } else {
        
            setCaretPos(new Point(caretPos.x-1, caretPos.y));
            
        }
        
        redraw();
        
    }
    
    public void moveCaretRight() {
        
        if (caretPos.y >= 0 && lines.size() > caretPos.y+1 && caretPos.x == lines.get(caretPos.y).length()) {
                
            setCaretPos(new Point(0, caretPos.y+1));
                
        } else {
        
            setCaretPos(new Point(caretPos.x+1, caretPos.y));
            
        }
        
        redraw();
        
    }
        
    public void moveCaretWordLeft() {
        
        int start = linedPosToNonLinedPos(caretPos)-2;
        
        while (start > 0 && text.charAt(start) == ' ') {
            
            start--;
            
        } 

        int newPos = text.lastIndexOf(' ', start);
        
        setCaretPos(nonLinedPosToLinedPos(newPos+1));
        redraw();
        
    }
    
    public void moveCaretWordRight() {
        
        int newPos = text.indexOf(' ', linedPosToNonLinedPos(caretPos));
        
        if (newPos < 0) {
            
            setCaretPos(nonLinedPosToLinedPos(text.length()));
            
        } else {
            
            while (newPos < text.length() && text.charAt(newPos) == ' ') {
                
                newPos++;
                
            }
            
            setCaretPos(nonLinedPosToLinedPos(newPos));
            
        }
        
        redraw();
        
    }
        
    public void startSelect() {
        
        if (!selecting) {
        
            selecting = true;
            
            if (equal(selectionStart, selectionEnd) && selectionStart.x == 0 && selectionStart.y == 0) {
            
                selectionStart = new Point(caretPos.x, caretPos.y);
                selectionEnd = new Point(caretPos.x, caretPos.y);
                
            }
            
        }
        
    }
    
    public void endSelect() {
        
        selecting = false;
        
    }
        
    public void deselect() {
        
        selecting = false;
        selectionStart = new Point(0, 0);
        selectionEnd = new Point(0, 0);
        redraw();
        
    }
    
    public void setCaretPos(Point pos) {
        
        if (pos.y < 0) {
            
            caretPos.y = 0;
            
        } else if (pos.y >= lines.size()) {
            
            caretPos.y = lines.size()-1;
            
        } else {
            
            caretPos.y = pos.y;
            
        }

        if (lines.size() > 0) {
        
            String line = lines.get(caretPos.y);
        
            if (pos.x < 0) {
            
                caretPos.x = 0;
            
            } else if (pos.x > line.length()) {
            
                caretPos.x = line.length();
            
            } else {
            
                caretPos.x = pos.x;
            
            }
        
            if (selecting) {
                
                selectionEnd = new Point(caretPos.x, caretPos.y);
                redraw();
                
            } else if (!equal(selectionStart, selectionEnd) || selectionStart.x != 0 || selectionStart.y != 0) {
                
                selectionStart = new Point(0, 0);
                selectionEnd = new Point(0, 0);
                
            }
            
            caret.setPosition(textPosToPixelPos(caretPos));
            parent.scrollTo(caret.getPosition().y);
            
        } else {
            
            caretPos.x = 0;
            caret.setPosition(new Point(0, 0));
            parent.scrollTo(0);
            
        }
        
    }
    
    private int widthOf(String text) {
        
        return evilHack.textExtent(text).x;
        
    }
    
    public void drawBefore(GC gc, Rectangle redrawArea) {

        gc.setFont(font);
        
        for (int i=0; i<lines.size(); i++) {
            
            if (fontHeight*i+fontHeight>redrawArea.y && fontHeight*i < redrawArea.y+redrawArea.height) {
            
                gc.drawText(lines.get(i), -redrawArea.x, fontHeight*i-redrawArea.y, true);
                
            }
            
        }
        
        if (!selectionStart.equals(selectionEnd)) {
            
            Point start;
            Point end;
            
            if (selectionStart.y < selectionEnd.y || (selectionStart.y == selectionEnd.y && selectionStart.x < selectionEnd.x)) {
                
                start = selectionStart;
                end = selectionEnd;
                
            } else {
                
                start = selectionEnd;
                end = selectionStart;
                
            }
            
            Point current = new Point(start.x, start.y);
			gc.setXORMode(true);
			gc.setForeground(ColorCache.get(255, 255, 255));
			gc.setBackground(ColorCache.get(255, 255, 255));            
            
            while (true) {
                
                if (current.y < end.y) {
                    
                    drawRectangleToEnd(gc, current, redrawArea);
                    current.x = 0;
                    current.y++;
                    
                } else {
                    
                    drawRectangleTo(gc, current, end, redrawArea);
                    break;
                    
                }
                
            }
            
            gc.setXORMode(false);
            
        }
        
    }
    
    private void drawRectangleToEnd(GC gc, Point from, Rectangle redrawArea) {
        
        if (lines.size() > from.y) {
            
            String line = lines.get(from.y);
            Point start = textPosToPixelPos(from);
            Point end = textPosToPixelPos(new Point(line.length(), from.y));
            
            if (start.y < redrawArea.y+redrawArea.height && end.y+fontHeight > redrawArea.y) {
            
                gc.fillRectangle(new Rectangle(start.x-redrawArea.x, start.y-redrawArea.y, end.x-start.x, end.y-start.y+fontHeight));
                
            }
            
        }
        
    }
    
    private void drawRectangleTo(GC gc, Point from, Point to, Rectangle redrawArea) {
        
        if (lines.size() > from.y) {
            
            Point start = textPosToPixelPos(from);
            Point end = textPosToPixelPos(to);

            if (start.y < redrawArea.y+redrawArea.height && end.y+fontHeight > redrawArea.y) {
                
                gc.fillRectangle(new Rectangle(start.x-redrawArea.x, start.y-redrawArea.y, end.x-start.x, end.y-start.y+fontHeight));
                
            }
            
        }
        
    }
    
    private Point textPosToPixelPos(Point textPos) {
        
        if (lines.size() <= 0 || textPos.y < 0) {
            
            return new Point(0, 0);
            
        } else if (textPos.y >= lines.size()) {
            
            int y = (lines.size()-1)*fontHeight;
            String line = lines.get(lines.size()-1);
            return new Point(textPosToPixelPos(line, line.length()), y);
            
        } else {
            
            int y = textPos.y*fontHeight;
            String line = lines.get(textPos.y);
            return new Point(textPosToPixelPos(line, textPos.x), y);
            
        }
        
    }
    
    private int textPosToPixelPos(String line, int textPos) {
        
        if (textPos >= 0 && textPos <= line.length()) {
            
            return evilHack.textExtent(line.substring(0, textPos)).x;
            
        } else if (textPos > line.length()) {
            
            return evilHack.textExtent(line).x;
            
        }
        
        return 0;
        
    }
        
    public int pixelPosToTextPos(String line, int x) {
        
        int currentPos = 0;
        int newPos = currentPos;
        
        while (true) {
            
            int currentPixelPos = textPosToPixelPos(line, currentPos);
            
            if (x < currentPixelPos && currentPos > 0) {
                
                newPos = currentPos - 1;
                
            } else if (x > currentPixelPos && currentPos < line.length()) {
                
                newPos = currentPos + 1;
                
            } else {
                
                break;
                
            }
            
            int newPixelPos = textPosToPixelPos(line, newPos);
            
            if (x > currentPixelPos && x < newPixelPos) {
                
                if (newPixelPos - x < x - currentPixelPos) {
                    
                    currentPos = newPos;
                    
                }
                
                break;
                
            } else if (x > newPixelPos && x < currentPixelPos) {
                
                if (x-newPixelPos < currentPixelPos-x) {
                    
                    currentPos = newPos;
                    
                }
                
                break;
                
            } else {
                
                currentPos = newPos;
                
            }
            
        }
        
        return currentPos;
        
    }
    
    public Point pixelPosToTextPos(Point pixelPos) {
        
        if (lines.size() > 0) {
        
            Point result = new Point(0, pixelPos.y/fontHeight);
        
            if (result.y < 0) {
            
                result.y = 0;
            
            } else if (result.y >= lines.size()) {
            
                result.y = lines.size()-1;
            
            }
        
            result.x = pixelPosToTextPos(lines.get(result.y), pixelPos.x);
            return result;
            
        } else {
            
            return new Point(0, 0);
            
        }
        
    }
    
    public void setSize(Point size) {
        
        if (size.x != area.width) {
            
            super.setSize(size);
            updateLines();
            
        }
        
    }

    public boolean capturesMouse() {
        
        return true;
        
    }
        
    public void mousePress(Point position, int button) {
        
        super.mousePress(position, button);
        
        if (!parent.isSelected()) {
        
            KeyboardManager.getSingleton().setState(new MultilineTextBoxState(parent));
            
        }
        
        selecting = true;
        setCaretPos(pixelPosToTextPos(position));
        selectionStart = new Point(caretPos.x, caretPos.y);
        redraw();
        getMouseFocus();
                
    }
    
    public void mouseMoving(Point position) {
        
        super.mouseMoving(position);
        
        if (isMouseDown()) {
        
            setCaretPos(pixelPosToTextPos(position));
            
        }
        
    }
    
    public void mouseRelease(Point position, int button) {
        
        super.mouseRelease(position, button);
        selecting = false;
        releaseMouseFocus();
        
    }
        
    public void deleteLines(int number) {

        int i = 0;
        int chars = 0;
        
        while (lines.size() > 0 && i < number) {
            
            chars += lines.get(0).length();
            
            if (forcedReturn.get(0).booleanValue()) {
                
                chars += StringUtil.NEWLINE.length();
                
            }
            
            lines.remove(0);
            forcedReturn.remove(0);
            i++;
            
        }
        
        text = text.substring(chars);
        
    }
    
    private void updateLines() {
        
        lines.clear();
        forcedReturn.clear();
        appendLines(text);
        
    }
    
    private void appendLines(String newText) {
        
        if (area.width > 20) {
        
//            lines.clear();
//            forcedReturn.clear();
//            String[] newLines = newText.split("\n", -1);
            String[] newLines = newText.split(StringUtil.NEWLINE, -1);
            
            for (int i=0; i<newLines.length; i++) {
                
                String line = newLines[i];
                
                if (widthOf(line) <= area.width) {
                    
                    lines.add(line);
                    forcedReturn.add(new Boolean(true));
                    
                } else {
                    
                    String temp = "";
                    String nextWord = "";
                    
                    while (line.length() > 0) {
                        
                        int currentSpace = line.indexOf(' ');
                        
                        if (currentSpace > 0) {
                            
                            nextWord = line.substring(0, currentSpace+1);
                            
                        } else {
                            
                            nextWord = line;
                            
                        }
                        
                        if (widthOf(temp)+widthOf(nextWord) > area.width) {
                            
                            if (temp.length() == 0) {
                                
                                int cap = Utils.capText(evilHack, line, area.width, "");
                                lines.add(nextWord.substring(0, cap));
                                forcedReturn.add(new Boolean(false));
                                line = line.substring(cap);
                                
                            } else {
                                
                                lines.add(temp);
                                forcedReturn.add(new Boolean(false));
                                temp = "";
                                
                            }
                            
                        } else {
                            
                            temp += nextWord;
                            line = line.substring(nextWord.length());
                            
                        }
                        
                    }
                    
                    if (temp.length() > 0) {
                        
                        lines.add(temp);
                        forcedReturn.add(new Boolean(true));
                        
                    }
                    
                }
                
            }
            
            if (lines.size() > 0) {
            
                super.setSize(new Point(area.width, lines.size()*fontHeight));
                
            } else {
            
                super.setSize(new Point(area.width, fontHeight));
                
            }
            
            setCaretPos(caretPos);
            
        }
        
    }
    
/*    private void updateLines() {
        
        if (area.width > 20) {
        
            lines.clear();
            forcedReturn.clear();
            String[] newLines = text.split("\n");
            
            for (int i=0; i<newLines.length; i++) {
                
                String line = newLines[i];
                
                if (widthOf(line) <= area.width) {
                    
                    lines.add(line);
                    forcedReturn.add(new Boolean(true));
                    
                } else {
                    
                    String temp = "";
                    String nextWord = "";
                    
                    while (line.length() > 0) {
                        
                        int currentSpace = line.indexOf(' ');
                        
                        if (currentSpace > 0) {
                            
                            nextWord = line.substring(0, currentSpace+1);
                            
                        } else {
                            
                            nextWord = line;
                            
                        }
                        
                        if (widthOf(temp)+widthOf(nextWord) > area.width) {
                            
                            if (temp.length() == 0) {
                                
                                int cap = Utils.capText(evilHack, line, area.width, "");
                                lines.add(nextWord.substring(0, cap));
                                forcedReturn.add(new Boolean(false));
                                line = line.substring(cap);
                                
                            } else {
                                
                                lines.add(temp);
                                forcedReturn.add(new Boolean(false));
                                temp = "";
                                
                            }
                            
                        } else {
                            
                            temp += nextWord;
                            line = line.substring(nextWord.length());
                            
                        }
                        
                    }
                    
                    if (temp.length() > 0) {
                        
                        lines.add(temp);
                        forcedReturn.add(new Boolean(true));
                        
                    }
                    
                }
                
            }
            
            super.setSize(new Point(area.width, lines.size()*fontHeight));
            setCaretPos(caretPos);
            
        }
        
    } */
    
    private boolean equal(Point p1, Point p2) {
        
        return (p1.x == p2.x) && (p1.y == p2.y);
        
    }
    
    private boolean lessThan(Point p1, Point p2) {
        
        return (p1.y < p2.y) || (p1.y == p2.y && p1.x < p2.x);
        
    }

    public void lostOwnership(Clipboard arg0, Transferable arg1) {
        
    }
    
}
