/*******************************************************************************
* 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 07-Nov-2004
 */
package uk.ac.ic.doc.kevlar.gui.internal.layout;

import org.eclipse.swt.graphics.Point;

/**
 * Defines an interface through which layouts can be alterted
 * of changes to the pipeline.
 * 
 * Layouts have complete control over the positions of programs
 * and the paths taken by pipes. The user can suggest a
 * preferred position of a program, which ideally the layout
 * should try to position the program near to.
 * 
 * Layouts have no control over the sizes of programs. This is
 * because a program's size depends greatly on its visual
 * representation (i.e number of inputs, outputs, arguments and
 * whether it's expanded or not). Layouts are alerted when a
 * program's size changes and should simply update their internal
 * state and move other programs if necessary.
 * 
 * These methods do not return any value, any alterations that need
 * to be made to programs or pipes should be done using call-back.
 * 
 * These methods are run in the UI thread, and so should not block
 * the thread for large amounts of time (this will cause poor
 * response). Please move any lengthy operations into separate
 * threads and call-back when they complete. Note that other layout
 * methods could be called in the meantime, so some system of
 * queueing/overriding calls should be used.
 * 
 * @author Marc
 **/
public interface ILayout {

    /**
     * Requests the position at which the layout will position the next
     * program to be added.
     * 
     * @return the position where the next program is to be placed
     */
    public Point newProgramPosition();
    
    /**
     * Alerts the layout that a new program is being added.
     * 
     * @param program the program to be added
     */
    public void addProgram(ILayoutProgram program);

    /**
     * Alerts the layout that a new program is being added,
     * and provides a suggested initial position.
     * 
     * @param program the program to be added
     * @param suggested the suggested position of the program
     */
    public void addProgram(ILayoutProgram program, Point suggested);

    /**
     * Alerts the layout that a new program is being added, and an output
     * on another program is selected. This means the new program is likely
     * to have one of its inputs connected up to the output program, so
     * it should be placed on the right of the output program.
     * 
     * @param program the program to be added
     * @param output the program whose output is selected
     */
    public void addProgramAsInput(ILayoutProgram program, ILayoutProgram output);
    
    /**
     * Alerts the layout that a new program is being added, and an input
     * on another program is selected. This means the new program is likely
     * to have one of its outputs connected up to the input program, so
     * it should be placed on the left of the input program.
     * 
     * @param program the program to be added
     * @param input the program whose input is selected
     */
    public void addProgramAsOutput(ILayoutProgram program, ILayoutProgram input);
    
    /**
     * Changes the suggested position of the given program.
     * 
     * The layout should call back the program to set its
     * actual position based on its new suggested position.
     * 
     * @param program the program to change the position of
     * @param position the new suggested position of the program
     */
    public void suggestProgramPosition(ILayoutProgram program, Point position);

    /**
     * Alerts the layout that a program is being resized.
     * 
     * The layout has no control over the size of programs;
     * it should simply update its internal representation.
     * 
     * @param program the program to be added
     * @param size the new size of the program
     */
    public void forceProgramSize(ILayoutProgram program, Point size);
    

    /**
     * Alerts the layout that a program is being removed.
     * 
     * @param program the program to be added 
     */
    public void removeProgram(ILayoutProgram program);
    

    /**
     * Alerts the layout that a new pipe is being added.
     * 
     * @param pipe the pipe to be added
     */
    public void addPipe(ILayoutPipe pipe);

    /**
     * Alerts the layout that a pipe's start and/or end point
     * has changed.
     * 
     * The layout should call back the pipe, removing the
     * existing path and setting a new path between the
     * start and end point.
     * 
     * @param pipe the pipe being altered
     * @param start the pipe's new start position
     * @param end the pipe's new end position
     */
    public void alterPipe(ILayoutPipe pipe, Point start, Point end);

    /**
     * Alerts the layout that a pipe is being removed.
     * 
     * @param pipe the pipe being removed 
     **/
    public void removePipe(ILayoutPipe pipe);
    
    /**
     * Alerts the layout that multiple move events are likely
     * to occur.
     * 
     * This will often be used when the user is dragging a
     * program, so the layout should use a quick method to
     * move other programs and update pipes in order to 
     * provide smooth movement.
     */
    public void startQuickMove();
    
    /**
     * Alerts the layout of the end of multiple move events.
     * 
     * At this point the layout should perform any processing
     * of the ignored events received during the quick move
     * period.
     */
    public void stopQuickMove();
    
}
