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

  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/vtkXMLKWOpenFilePropertiesReader.h"

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

#include <vtksys/SystemTools.hxx>

vtkStandardNewMacro(vtkXMLKWOpenFilePropertiesReader);
vtkCxxRevisionMacro(vtkXMLKWOpenFilePropertiesReader, "$Revision: 1.6 $");

//----------------------------------------------------------------------------
const char* vtkXMLKWOpenFilePropertiesReader::GetRootElementName()
{
  return "KWOpenFileProperties";
}

//----------------------------------------------------------------------------
vtkXMLKWOpenFilePropertiesReader::vtkXMLKWOpenFilePropertiesReader()
{
  this->FilePatternDirectory = 0;
}

//----------------------------------------------------------------------------
vtkXMLKWOpenFilePropertiesReader::~vtkXMLKWOpenFilePropertiesReader()
{
  this->SetFilePatternDirectory(0);
}

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

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

  // Get attributes

  double dbuffer3[3];
  int ibuffer6[6], ibuffer3[3], ival, i;
  const char *cptr;

  if (elem->GetVectorAttribute("Spacing", 3, dbuffer3) == 3)
    {
    obj->SetSpacing(dbuffer3);
    }

  if (elem->GetVectorAttribute("Origin", 3, dbuffer3) == 3)
    {
    obj->SetOrigin(dbuffer3);
    }

  cptr = elem->GetAttribute("DistanceUnits");
  if (cptr)
    {
    obj->SetDistanceUnits(cptr);
    }

  for (i = 0; i < VTK_MAX_VRCOMP; i++)
    {
    char scalarunits[256];
    sprintf(scalarunits, "ScalarUnits%d", i);
    cptr = elem->GetAttribute(scalarunits);
    if (cptr)
      {
      obj->SetScalarUnits(i, cptr);
      }
    }
  
  if (elem->GetScalarAttribute("IndependentComponents", ival))
    {
    obj->SetIndependentComponents(ival);
    }

  if (elem->GetScalarAttribute("NumberOfScalarComponents", ival))
    {
    obj->SetNumberOfScalarComponents(ival);
    }

  if (elem->GetScalarAttribute("ScalarType", ival))
    {
    obj->SetScalarType(ival);
    }
  
  if (elem->GetVectorAttribute("WholeExtent", 6, ibuffer6) == 6)
    {
    obj->SetWholeExtent(ibuffer6);
    }

  if (elem->GetVectorAttribute("FileOrientation", 3, ibuffer3) == 3)
    {
    obj->SetSliceAxis(ibuffer3[0]);
    obj->SetRowAxis(ibuffer3[1]);
    obj->SetColumnAxis(ibuffer3[2]);
    }

  if (elem->GetScalarAttribute("BigEndianFlag", ival))
    {
    if (ival == 1)
      {
      obj->SetDataByteOrderToBigEndian();
      }
    else if (ival == 0)
      {
      obj->SetDataByteOrderToLittleEndian();
      }
    }

  // The FilePattern is stored as "relative" by the XML write (i.e., its
  // directory was removed) if DiscardFilePatternDirectory is set to 1 
  // by the writer vtkXMLKWOpenFilePropertiesWriter.
  // Try to fix it if FilePatternDirectory is set.
  // First check to see if we are using an old "full path" FilePattern by
  // checking is there is a valid directory part, otherwise try to
  // set the full FillPattern by using a user specified FilePatternDirectory
    
  cptr = elem->GetAttribute("FilePattern");
  if (cptr)
    {
    vtksys_stl::string cptr_dir = 
      vtksys::SystemTools::GetFilenamePath(cptr);
    if ((cptr_dir.size() && 
         vtksys::SystemTools::FileIsDirectory(cptr_dir.c_str())) ||
        !this->FilePatternDirectory)
      {
      obj->SetFilePattern(cptr);
      }
    else
      {
      vtksys_stl::string fp_dir(this->FilePatternDirectory);
      fp_dir = fp_dir + "/" + cptr;
      obj->SetFilePattern(fp_dir.c_str());
      }
    }

  if (elem->GetScalarAttribute("FileDimensionality", ival))
    {
    obj->SetFileDimensionality(ival);
    }

  if (elem->GetScalarAttribute("Scope", ival))
    {
    obj->SetScope(ival);
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkXMLKWOpenFilePropertiesReader::IsValid()
{
  // We never found the root element

  if (!this->LastParsedElement)
    {
    return 0;
    }

  // We found it, check the mandatory attribs

  return (this->LastParsedElement->GetAttribute("Spacing") &&
          this->LastParsedElement->GetAttribute("Origin"));
}

//----------------------------------------------------------------------------
int vtkXMLKWOpenFilePropertiesReader::IsDescribingPatternSeries()
{
  // It better be valid first

  if (!this->IsValid())
    {
    return 0;
    }

  // We found it, check the mandatory attribs

  return (this->LastParsedElement->GetAttribute("WholeExtent") &&
          this->LastParsedElement->GetAttribute("FilePattern"));
}

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

  os << indent << "FilePatternDirectory: " 
     << (this->FilePatternDirectory ? this->FilePatternDirectory : "(none)") 
     << endl;
}
