/*
 * @(#)$RCSfile: SelectionDragInteractor.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:51:23 $
 *
 * (C) Copyright IBM Corp. 1998-1999.  All Rights Reserved.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */
package com.ibm.richtext.textpanel;

import java.text.BreakIterator;

import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import com.ibm.richtext.textformat.TextOffset;

final class SelectionDragInteractor extends Behavior implements Runnable {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
    private TextComponent fTextComponent;
    private TextSelection fSelection;
    private RunStrategy fRunStrategy;
    
    private TextOffset fAnchorStart; // aliases text offsets - client beware
    private TextOffset fAnchorEnd;
    private TextOffset fCurrent;

    private final boolean fWasZeroLength;

    private int fCurrentX;
    private int fCurrentY;
    private boolean fMouseOutside;

    private Thread fAutoscrollThread = null;
    private boolean fThreadRun = true;

    private static final int kScrollSleep = 300;

    public SelectionDragInteractor(TextSelection selection,
                                   TextComponent textComponent,
                                   RunStrategy runStrategy,
                                   TextOffset anchorStart,
                                   TextOffset anchorEnd,
                                   TextOffset current,
                                   int initialX,
                                   int initialY,
                                   boolean wasZeroLength) {

        fTextComponent = textComponent;
        fSelection = selection;
        fRunStrategy = runStrategy;
        fAnchorStart = anchorStart;
        fAnchorEnd = anchorEnd;
        fCurrent = current;

        fCurrentX = initialX;
        fCurrentY = initialY;
        fMouseOutside = false;

        fWasZeroLength = wasZeroLength;
        
        setSelection();
    }
    
    public boolean textControlEventOccurred(Behavior.EventType event, Object what) {

        return true;
    }

    public boolean focusGained(FocusEvent event) {

        return true;
    }

    public boolean focusLost(FocusEvent event) {

        return true;
    }

    public boolean keyPressed(KeyEvent event) {

        return true;
    }

    public boolean keyTyped(KeyEvent event) {

        return true;
    }

    public boolean keyReleased(KeyEvent event) {

        return true;
    }

    public synchronized boolean mouseDragged(MouseEvent e) {

        int x = e.getX(), y = e.getY();
        if (fCurrentX != x || fCurrentY != y) {
            fCurrentX = x;
            fCurrentY = y;
            processMouseLocation();
        }
        return true;
    }

    public synchronized boolean mouseEnter(MouseEvent e) {

        fMouseOutside = false;
        return true;
    }

    public synchronized boolean mouseExited(MouseEvent e) {

        if (fAutoscrollThread == null) {
            fAutoscrollThread = new Thread(this);
            fAutoscrollThread.start();
        }
        fMouseOutside = true;
        notify();

        return true;
    }

    public synchronized boolean mouseReleased(MouseEvent e) {

        fMouseOutside = false;
        fThreadRun = false;
        if (fAutoscrollThread != null) {
            fAutoscrollThread.interrupt();
        }
        
        removeFromOwner();
        boolean isZeroLength = TextSelection.rangeIsZeroLength(fAnchorStart,
                                                               fAnchorEnd,
                                                               fCurrent);
        fSelection.mouseReleased(isZeroLength != fWasZeroLength);

        return true;
    }

    private void processMouseLocation() {

        fTextComponent.scrollToShow(fCurrentX, fCurrentY);
        fTextComponent.pointToTextOffset(fCurrent, fCurrentX, fCurrentY, null, true);
        setSelection();
    }

    private void setSelection() {

        if (fCurrent.greaterThan(fAnchorEnd)) {
            fSelection.advanceToNextBoundary(fCurrent);
            fSelection.setSelRangeAndDraw(fAnchorStart, fCurrent, fAnchorStart);
        }
        else if (fCurrent.lessThan(fAnchorStart)) {
            fSelection.advanceToPreviousBoundary(fCurrent);
            fSelection.setSelRangeAndDraw(fCurrent, fAnchorEnd, fAnchorStart);
        }
        else {
            fCurrent.assign(fAnchorEnd);
            fSelection.setSelRangeAndDraw(fAnchorStart, fAnchorEnd, fAnchorStart);
        }
    }

    public void run() {

        Runnable doMouseLoc = new Runnable() {
            public void run() {
                processMouseLocation();
            }
        };
        
        while (fThreadRun) {

            try {
                Thread.sleep(kScrollSleep);
            }
            catch(InterruptedException e) {
                return; // just quit scrolling
            }

            synchronized(this) {

                while (!fMouseOutside) {
                    try {
                        wait();
                    }
                    catch(InterruptedException e) {
                        return; // just quit scrolling
                    }
                }

                fRunStrategy.doIt(doMouseLoc);
            }
        }
    }
}
