/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME vtkVVFileInstance - a file instance class.
// .SECTION Description
// This class stores an instance of a loaded file, i.e. one (or more) 
// filename(s) and the resulting data items.

#ifndef __vtkVVFileInstance_h
#define __vtkVVFileInstance_h

#include "vtkKWObject.h"
#include "XML/vtkXMLIOBaseMacros.h" // Needed for XML reader/writer macros

class vtkVVFileInstanceInternals;
class vtkVVDataItemPool;
class vtkVVWindowBase;
class vtkKWOpenWizard;
class vtkCollection;
class vtkKWOpenFileProperties;
class vtkKWDataTransfer;

class VTK_EXPORT vtkVVFileInstance : public vtkKWObject
{
public:
  static vtkVVFileInstance* New();
  vtkTypeRevisionMacro(vtkVVFileInstance,vtkKWObject);
  virtual void PrintSelf(ostream& os, vtkIndent indent);
  //BTX
  vtkKWGetXMLReaderWriterObjectsMacro();
  //ETX

  // Description:
  // Set/Get the name of the file instance. 
  // As a rule of thumb, the file instance name should be unique enough that
  // it can be used efficiently to find the instance inside a 
  // vtkVVFileInstancePool. 
  // The filename to the file itself or the *first* filename of a series is
  // a reasonable choice.
  vtkSetStringMacro(Name);
  vtkGetStringMacro(Name);

  // Description:
  // Set/Get the filenames. Provision is made for more than one filenames in
  // case we are loading a series, which is still considered as a single file
  // unit.
  virtual int GetNumberOfFileNames();
  virtual void AddFileName(const char *);  
  virtual const char* GetNthFileName(int i);
  virtual void DeleteAllFileNames();

  // Description:
  // Convenience method to erase all filenames and set the first one.
  // Note: this will also erase the URIs associated to all filenames.
  virtual void SetFileName(const char *);  
  virtual const char* GetFileName();  

  // Description:
  // Query if a filename matches one of the filenames in this instance.
  // Return 1 on success, 0 otherwise
  virtual int HasFileName(const char *);  

  // Description:
  // Query if *all* the filenames in one instance match *all* the filenames in
  // this instance.
  // Return 1 on success, 0 otherwise
  virtual int HasSameFileNames(vtkVVFileInstance *instance);

  // Description:
  // The RemoteIO framework allows a remote filename to be specified. 
  // * The framework consists of a source URI, this is usually on a server.
  // * The destination URI is the destination file the source is downloaded
  //   as in the cache directory.
  // For example,
  //   fileInstance->SetFileName("Paper001/Data1/Image01.dcm");
  //   fileInstance->SetFileNameURI("Paper001/Dataset1/Image01.dcm",
  //                                "http://.../Paper001/Dataset1.tar.gz"
  //                                "Paper001/Data1/Data.tar.gz");
  // This will result in the cache directory containing the datasets..
  //   .VolView1.x/
  //     |
  //     -- Data1/
  //          |
  //          -- Data.tar.gz
  //
  virtual void SetFileNameURI(const char *filename, 
                              const char *sourceURI,
                              const char *destinationURI);  
  virtual const char* GetNthFileNameSourceURI(int i);
  virtual const char* GetNthFileNameDestinationURI(int i);

  // Description:
  // Add a preview URI filename. You can have more than 1 preview URI. 
  // These must be specified in order.
  //
  //   AddFileNamePreviewURI("Paper01/CTHead001.dcm, 
  //                         "Paper01/CTHead.mha", 
  //                         "http://..../HostedPreviewArchive.tar.gz"
  //                         "Paper01/DownloadedPreviewArchive.tar.gz");
  virtual void AddFileNamePreviewURI(const char *filename, 
                                     const char *previewFilename,
                                     const char *previewSourceURI,
                                     const char *previewDestinationURI);
  virtual const char *GetNthFileNamePreviewFilename(int i);
  virtual const char *GetNthFileNamePreviewSourceURI(int i);
  virtual const char *GetNthFileNamePreviewDestinationURI(int i);

  // Description:
  // Set/Get a relocation directory. 
  // If this is set, whenever a filename is added, the instance first
  // checks if it exists, and if that is not the case, attempt to locate
  // it in the relocation directory and update that location.
  virtual void SetRelocationDirectory(const char *dir);
  vtkGetStringMacro(RelocationDirectory);

  // Description:
  // Load the data items according to the current filenames or a specific
  // filename.
  // Note that an OpenWizard is created, invoked, and passed to
  // LoadFromOpenWizard. If the OpenFileProperties are set at this point,
  // they will be used explicitly by the Open Wizard (as opposed to guessed
  // and/or retrieved from a VVI file).
  // Return 1 on success, 0 otherwise.
  virtual int Load();

  // Description:
  // Load the data items according to URI's specified if any.
  // Return 1 if the previewURI or cached preview file is loaded, 
  //        2 if the cached URI/file is loaded.
  //        0 on Failure
  virtual int LoadFromURIs();

  // Description:
  // Load the data items from an openwizard, update the current filename(s)
  // accordingly. 
  // IMPORTANT: note that openwizard is *not* Invoke()'ed, it is assumed
  // it was invoked previously (say, by Load()). Its last reader is used 
  // directly at this point.
  // Return 1 on success, 0 otherwise.
  virtual int LoadFromOpenWizard(vtkKWOpenWizard *openwizard);

  // Description:
  // The data items. 
  // Note that each DataItem in the DataItemPool may store a pointer to the file
  // instance that was loaded to create them (see vtkVVDataItem::FileInstance).
  vtkGetObjectMacro(DataItemPool, vtkVVDataItemPool);

  // Description:
  // UnLoad the data items. 
  virtual void UnLoad();

  // Description:
  // Query if any of the data item associated to this file has a
  // representation (say a 2D or 3D view) in a given window.
  // This method  just loops over all data item and call
  // vtkVVDataItem::HasRenderWidgetInWindow
  virtual int HasRenderWidgetInWindow(vtkVVWindowBase *win);

  // Description:
  // Add/Remove default widgets for all the data item to a window
  // For image/volume data, this will create the default 3D view, 2D views,
  // lightbox, etc.
  // This method  just loops over all data item and call
  // vtkVVDataItem::AddDefaultRenderWidgets or 
  // vtkVVDataItem::RemoveDefaultRenderWidgets
  virtual void AddDefaultRenderWidgets(vtkVVWindowBase *);
  virtual void RemoveDefaultRenderWidgets(vtkVVWindowBase *);

  // Description:
  // Get the collection of data transfers that are downloading data for this
  // file.
  vtkGetObjectMacro(DataTransferCollection, vtkCollection);
  virtual void CancelAllDataTransfers();

  // Description:
  // Query is a specific data transfer object is part of our data transfer
  // collection.
  virtual int HasDataTransfer(vtkKWDataTransfer *);

  // Description:
  // Set/Get the parameters that were used to open this file using the
  // openwizard. These are the same as the one that get written to the
  // corresponding .vvi file, but we want to keep them around so that
  // they can be serialized to a session file.
  // It is ref counted.
  virtual void SetOpenFileProperties(vtkKWOpenFileProperties *widget);
  vtkGetObjectMacro(OpenFileProperties, vtkKWOpenFileProperties);

  // Description:
  // Query if the open properties used for a given instance match the open
  // properties used for this instance. They do NOT have to be the 
  // same open file properties object of course, the test is performed
  // on the individual internal properties (by calling 
  // vtkKWOpenFileProperties::IsEqual())
  // Return 1 on success, 0 otherwise
  virtual int HasSameOpenFileProperties(vtkVVFileInstance *instance);

protected:
  vtkVVFileInstance();
  ~vtkVVFileInstance();

  // Description:
  // Data item name
  char *Name;
  
  // Description:
  // Series data
  vtkVVDataItemPool *DataItemPool;
  
  // Description:
  // Relocation directory
  char *RelocationDirectory;
  
  // Description:
  // PIMPL Encapsulation for STL containers
  vtkVVFileInstanceInternals *Internals;

  // Description:
  // Try to relocate dead files (files that do no exist) by looking up for
  // the same filename in a different candidate directory.
  // Return the number of relocated files.
  virtual int RelocateDeadFiles(const char *candidate_dir);
  
  // Description:
  // Remote data transfer handler
  vtkCollection * DataTransferCollection;

  // Description:
  // The open file properties
  vtkKWOpenFileProperties *OpenFileProperties;

  // Description:
  // Load specific filename
  virtual int Load(const char *filename);

  // Description:
  // Load the data as a preview
  virtual int LoadPreview(const char *filename);

private:

  vtkVVFileInstance(const vtkVVFileInstance&); // Not implemented
  void operator=(const vtkVVFileInstance&); // Not implemented
};

#endif
