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

  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.

=========================================================================*/
#include "XML/vtkXMLVVFileInstanceReader.h"

#include "vtkObjectFactory.h"
#include "vtkVVFileInstance.h"
#include "vtkXMLDataElement.h"
#include "vtkStringArray.h"
#include "vtkKWOpenFileProperties.h"

#include "XML/vtkXMLVVFileInstanceWriter.h"
#include "XML/vtkXMLKWOpenFilePropertiesReader.h"

#include <vtksys/stl/string>
#include <vtksys/SystemTools.hxx>

vtkStandardNewMacro(vtkXMLVVFileInstanceReader);
vtkCxxRevisionMacro(vtkXMLVVFileInstanceReader, "$Revision: 1.17 $");

//----------------------------------------------------------------------------
const char* vtkXMLVVFileInstanceReader::GetRootElementName()
{
  return "VVFileInstance";
}

//----------------------------------------------------------------------------
int vtkXMLVVFileInstanceReader::Parse(vtkXMLDataElement *elem)
{
  if (!this->Superclass::Parse(elem))
    {
    return 0;
    }

  vtkVVFileInstance *obj = vtkVVFileInstance::SafeDownCast(this->Object);
  if (!obj)
    {
    vtkWarningMacro(<< "The VVFileInstance is not set!");
    return 0;
    }

  // Get Attributes

  obj->SetName(elem->GetAttribute("Name"));
  
  // Get nested elements

  vtkXMLDataElement *nested_elem;

  // Try to relocate the files on the fly if they are "dead" (i.e. if the
  // absolute path does not exist, try to find the files relative to the XML 
  // file we are parsing, if any)

  const char *parsed_from_file = elem->GetRoot()->GetAttribute(
    vtkXMLObjectReader::GetParsedFromFileAttributeName());
  if (parsed_from_file)
    {
    vtksys_stl::string path = 
      vtksys::SystemTools::GetFilenamePath(parsed_from_file);
    if (vtksys::SystemTools::FileExists(path.c_str()) &&
        vtksys::SystemTools::FileIsDirectory(path.c_str()))
      {
      obj->SetRelocationDirectory(path.c_str());
      }
    }

  // File Names

  obj->DeleteAllFileNames();
  
  int idx, nb_nested_elems = elem->GetNumberOfNestedElements();
  for (idx = 0; idx < nb_nested_elems; idx++)
    {
    nested_elem = elem->GetNestedElement(idx);
    if (!strcmp(nested_elem->GetName(), 
                vtkXMLVVFileInstanceWriter::GetFileNameElementName()))
      {
      const char *value = nested_elem->GetAttribute("Value");
      if (value)
        {
        obj->AddFileName(value);
        }

      // A URI for remote downloading - optional

      const char *sourceURI = 
        nested_elem->GetAttribute("SourceURI");
      const char *destinationURI = 
        nested_elem->GetAttribute("DestinationURI");
      if (sourceURI && destinationURI)
        {
        obj->SetFileNameURI(value, sourceURI, destinationURI);
        }

      // A Preview URI for remote downloading - optional

      const char *previewFile = 
        nested_elem->GetAttribute("PreviewFile");
      const char *previewSourceURI = 
        nested_elem->GetAttribute("PreviewSourceURI");
      const char *previewDestinationURI = 
        nested_elem->GetAttribute("PreviewDestinationURI");
      if (previewSourceURI && previewDestinationURI && previewFile)
        {
        obj->AddFileNamePreviewURI(value, previewFile, 
                                          previewSourceURI, 
                                          previewDestinationURI);
        }
      }
    }

  // Open File Properties

  vtksys_stl::string dir;
  if (obj->GetFileName())
    {
    dir = vtksys::SystemTools::GetFilenamePath(obj->GetFileName());
    }

  vtkKWOpenFileProperties *open_prop = vtkKWOpenFileProperties::New();
  vtkXMLKWOpenFilePropertiesReader *xmlr = 
    vtkXMLKWOpenFilePropertiesReader::SafeDownCast(
      open_prop->GetNewXMLReader());
  if (xmlr->ParseInElement(elem))
    {
    if (obj->GetOpenFileProperties())
      {
      obj->GetOpenFileProperties()->DeepCopy(open_prop);
      }
    else
      {
      obj->SetOpenFileProperties(open_prop); // ref counted
      }
    }
  open_prop->Delete();
  xmlr->Delete();

  return 1;
}

//----------------------------------------------------------------------------
void vtkXMLVVFileInstanceReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
