/*
 * This file is part of the Vamsas Client version 0.2. 
 * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite, 
 *  Andrew Waterhouse and Dominik Lindner.
 * 
 * Earlier versions have also been incorporated into Jalview version 2.4 
 * since 2008, and TOPALi version 2 since 2007.
 * 
 * The Vamsas Client is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * The Vamsas Client is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.
 */
package uk.ac.vamsas.client;

import java.beans.PropertyChangeListener;
import java.io.IOException;

/**
 * Defines the methods availabable to a vamsas application for interacting with
 * its Vorba agent created by an IClientFactory instance for a particular
 * session, user, and application handle. (it's VORBA, not CORBA!) LATER: add
 * exceptions for timeouts raised when there are problems accessing session data
 * (because another application is hogging it). LATER: think about situations
 * when two applications both want a ClientDocument at the same time - can one
 * have read-only access (and be told that another is about to update)
 */

public interface IClient {

  /**
   * Self-documenting/describing info for the application to present to the
   * user. LATER: formalise this for describing VAMSAS system, a particular
   * Vorba client agent, and a particular session.
   * 
   * @return string like VamsasClient v.1.1.1 (GPL) and whatever
   */
  public String getAbout();

  /**
   * convenience method to get the SessionUrn as a string (for passing directly
   * to a text box...).
   * 
   * @return current SessionUrn
   */
  public String getSessionUrn();

  /**
   * Returns a valid URN for other applications to connect to the vamsas
   * session.
   * 
   * @return session handle for this session.
   */
  public SessionHandle getSessionHandle();

  /**
   * Included for applications with several ClientHandle identities.
   * 
   * @return ClientHandle used to interact with other Vamsas applications.
   */
  public ClientHandle getClientHandle();

  /**
   * 
   * @return UserHandle used when interacting with other Vamsas applications.
   */
  public UserHandle getUserHandle();

  /**
   * Method called by client application on exit. Vorba will inform other
   * clients if they exist. If this is the last application in the session then
   * the session will be closed. Note: The application should be ready to handle
   * 'RequestToCloseDocument' events from the Vorba agent in the latter case and
   * so prompt the user to save the session locally. LATER: pick a better name ?
   */
  public void finalizeClient();

  /**
   * register handler for updates for the current session
   */
  public void addDocumentUpdateHandler(PropertyChangeListener evt);

  /**
   * get vamsas document with user and app specific data IClientDocuments are
   * not thread-safe. TODO: New exception for failed document lock.
   * 
   * @throws IOException
   *           if lock is not obtainable for the document in the session
   */
  public IClientDocument getClientDocument() throws IOException;

  /**
   * Queue new Vorba objects for storage and propagation to other clients (via
   * Event.DOCUMENT_UPDATE based notification of document change) New objects
   * without provenance information will be given a default entry using the
   * IClient's application, user (and session) handles Validity of
   * IClientDocument object instances after this call is implementation
   * dependent TODO: consider refactoring to remove the redundant
   * IClientDocument parameter for this method
   */
  public void updateDocument(IClientDocument newdoc);

  /**
   * Any application may call storeDocument to save a local copy of the current
   * vamsas document including all application specific entries.
   * 
   * @param location
   *          to write zip file
   */
  public void storeDocument(java.io.File location);

  /**
   * Any application may call importDocument to merge a stored vamsasDocument
   * into the current session. Note: use a IClientFactory's implementation to
   * make sessions out of vamsas documents TODO: this is not currently
   * implemented by SimpleClient - and may be dropped from the first version of
   * the interface. LATER: VAMSAS: The IClient implementation will handle all ID
   * 'relocations'
   * 
   * @param location
   */
  public void importDocument(java.io.File location);

  /**
   * Add a listener to a particular event chain. See uk.ac.vamsas.client.Events
   * for allowed values for EventChain. The EventChain value is passed as the
   * propertyName in the java.bean.PropertyChangeEvent LATER: extend class to
   * form own vamsas Event/Listener model.
   * 
   * @param EventChain
   *          Name of event. Blank/null registers handler for all events.
   * @param evt
   *          - event handler function.
   */
  public void addVorbaEventHandler(String EventChain, PropertyChangeListener evt);

  /**
   * Sets the update handler that will be called when any updates occur to
   * objects of type rootObject.
   * 
   * @param rootObject
   * @param handler
   */
  public void setUpdateHandler(IObjectUpdate handler);

  public IObjectUpdate getUpdateHandler(Class rootObject);

  public void removeUpdateHandler(Class rootObject);

  public IObjectUpdate[] getUpdateHandlers();

  /**
   * client application calls this to force the Vorba client to check for
   * updates immediately.
   * 
   */
  public void pollUpdate();

  /**
   * Client application calls this after any pre-session initialization
   * (registering of Handlers, etc) Exceptions are raised for any failures. Any
   * stateful calls to the session prior to this will result in an implicit call
   * to joinSession - if that results in an exception then the VamsasClient
   * should raise an Error. LATER: create VAMSAS exception hierarchy (in a
   * language agnostic manner)
   */
  public void joinSession() throws Exception;

  /**
   * get the Vamsas Pick Manager for registering pick handlers and sending
   * messages for the current session.
   * 
   * @return an object implementing IPickManager (which maybe the same as the
   *         IClient implementer)
   */
  public uk.ac.vamsas.client.picking.IPickManager getPickManager();

}
