//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt 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 "vtkCMBSceneV2WriterHelper.h"

#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkErrorCode.h"

#
#include <sys/types.h>
#include <sys/stat.h>
#include <vtksys/SystemTools.hxx>

vtkStandardNewMacro(vtkCMBSceneV2WriterHelper);

//-----------------------------------------------------------------------------
// The internals class mostly holds templated ivars that we don't want to
// expose in the header file.
class vtkCMBSceneV2WriterHelper::vtkSceneGenInternal
{
public:
  std::vector<vtkStdString> ObjectFileNames;

};
//-----------------------------------------------------------------------------
vtkCMBSceneV2WriterHelper::vtkCMBSceneV2WriterHelper()
{
  this->SetNumberOfInputPorts(0);

  this->FileName = 0;
  this->Text = 0;
  this->Mode = 0;
  this->PackageScene = 0;

  this->Internal = new vtkCMBSceneV2WriterHelper::vtkSceneGenInternal();
}

//-----------------------------------------------------------------------------
vtkCMBSceneV2WriterHelper::~vtkCMBSceneV2WriterHelper()
{
  this->SetFileName(0);
  this->SetText(0);

  if (this->Internal)
    {
    delete this->Internal;
    }

}

//-----------------------------------------------------------------------------
int vtkCMBSceneV2WriterHelper::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  if ( this->GetMode() == 1 )
    {
    //we are in check directory info mode
    this->ProcessFileNames();
    }
  else if ( this->GetMode() == 2 )
    {
    //we are in xml file writing mode
    if ( this->FileName == NULL || this->Text == NULL )
      {
      return 0;
      }

    std::ofstream out(this->FileName);
    out.write(this->Text, strlen(this->Text));
    out.close();
    }
  return 1;
}


//-----------------------------------------------------------------------------
void vtkCMBSceneV2WriterHelper::AddObjectFileName(const char *fname)
{
  this->Internal->ObjectFileNames.push_back(fname);
  this->Modified();
}

void vtkCMBSceneV2WriterHelper::RemoveAllObjectFileNames()
{
  this->Internal->ObjectFileNames.clear();
  this->Modified();
}

unsigned int vtkCMBSceneV2WriterHelper::GetNumberOfObjectFileNames()
{
  return static_cast<unsigned int>(this->Internal->ObjectFileNames.size());
}

const char *vtkCMBSceneV2WriterHelper::GetObjectFileName(unsigned int idx)
{
  return this->Internal->ObjectFileNames[idx].c_str();
}


//-----------------------------------------------------------------------------
void vtkCMBSceneV2WriterHelper::ProcessFileNames()
{
  std::string fullPath =
    vtksys::SystemTools::CollapseFullPath(this->FileName);
  std::string dataPath = vtksys::SystemTools::GetFilenamePath( fullPath );
  std::string relPath, fname, fnameFullPath;
  std::string fPath, fnameComp, newFile;

  for (unsigned int i = 0; i < this->Internal->ObjectFileNames.size(); i++)
    {
    fname = this->Internal->ObjectFileNames[i];

    fnameFullPath =
      vtksys::SystemTools::CollapseFullPath( fname.c_str());
    if (this->GetPackageScene())
      {
      // See if the file is in the same directory as the scene file
      // if its not we need to copy the file - do this by comparing th
      // paths
      fPath = vtksys::SystemTools::GetFilenamePath( fnameFullPath );
      fnameComp = vtksys::SystemTools::GetFilenameName( fname );

      if (fPath != dataPath)
        {
        newFile = dataPath;
        newFile.append("/");
        newFile.append(fnameComp);
        vtksys::SystemTools::CopyFileAlways(fnameFullPath.c_str(),
                                            newFile.c_str());
        }
      relPath = fnameComp;
      }
    else
      {
      relPath = vtksys::SystemTools::RelativePath(dataPath.c_str(),
                                                  fnameFullPath.c_str());
      }
    this->Internal->ObjectFileNames[i] = relPath;
    }
}

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

  os << indent << "File Name: "
     << (this->FileName ? this->FileName : "(none)") << "\n";

  os << indent << "Text: "
     << (this->Text ? this->Text : "(none)") << "\n";

  for (unsigned int i = 0; i < this->Internal->ObjectFileNames.size(); i++)
    {
    os << indent << "Object FileName[" << i << "]: "
       << this->Internal->ObjectFileNames[i] << endl;
    }

  os << indent << "Mode: " << this->Mode << endl;
  os << indent << "PackageScene: " << this->PackageScene << endl;
}


//----------------------------------------------------------------------------
int vtkCMBSceneV2WriterHelper::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  return VTK_OK;
}

