/*

  Implements FITS file name utilities (taylored by wxFileName):

  * GNU backup-file conventions

  * file-existing


  Copyright © 2013 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack 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 General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.

*/


#include "fitsfn.h"
#include <wx/wx.h>
#include <wx/regex.h>
#include <wx/filename.h>
#include <wx/dir.h>
#include <fitsio.h>

FITSFileName::FITSFileName(const wxString& name):
  version_control("existing"),
  simple_backup_suffix("~")
{
  // backup control
  wxString a;

  if( wxGetEnv("VERSION_CONTROL",&a) )
    version_control = a;

  if( wxGetEnv("SIMPLE_BACKUP_SUFFIX",&a) )
    simple_backup_suffix = a;

  // parse input name
  wxString basename,ext;
  if( ParseExt(name,basename,ext) )
    filename = basename;
  else
    filename = name;

  backup = Get(filename);

}

void FITSFileName::SetSuffix(const wxString& a) { simple_backup_suffix = a; }
void FITSFileName::SetControl(const wxString& a) { version_control = a; }
wxString FITSFileName::GetBackup() const { return backup; }
wxString FITSFileName::GetBaseName() const { return filename; }

bool FITSFileName::FileExists() const 
{ 
  int exists, status;
  status = 0;

  const char *path = filename.fn_str();
  fits_file_exists((char *)path,&exists,&status);

  return status == 0 && exists != 0;
}



wxString FITSFileName::Get(const wxString& name) const
{
  if( version_control == "none" || version_control == "off"  ) 

    return "";

  else if( version_control == "simple" || version_control == "never" )

    return name + simple_backup_suffix;

  else if( version_control == "numbered" || version_control == "t" )

    return NumberBackup(name,FindBackup(name)+1);

  else if( version_control == "existing" || version_control == "nil" ) {
	
    long n = FindBackup(name);
    if( n > 0 )
      return NumberBackup(name,n+1);
    else
      return name + simple_backup_suffix;
  }
  else {
    wxLogFatalError("Unknown backup method.");
    return "";
  }
}


long FITSFileName::FindBackup(const wxString& name) const
{
  wxString filespec = name + simple_backup_suffix + "*" + simple_backup_suffix;

  long count = 0;

  wxString pattern(".*"+simple_backup_suffix+"([0-9]+)"+simple_backup_suffix);
  wxRegEx re(pattern);

  if( ! re.IsValid() ) {
    wxLogFatalError("Regular expression pattern `"+pattern+"' is invalid.");
  }

  wxFileName fn(name);

  wxString path(fn.GetPath());
  if( path == "" )
    path = wxGetCwd();

  wxDir dir(path);
  if ( dir.IsOpened() ) {

    wxString filename;
    bool cont = dir.GetFirst(&filename,filespec,wxDIR_FILES);
    while ( cont ) {

      if( re.Matches(filename) ) {
      
	wxString a(re.GetMatch(filename,1));
	long n;
	if( a.ToLong(&n) && n > count )
	  count = n;
      }

      cont = dir.GetNext(&filename);
    }
  }
  return count;
}

wxString FITSFileName::NumberBackup(const wxString& name, long n) const
{
  return wxString::Format("%s%ld%s",name+simple_backup_suffix,n,simple_backup_suffix);
}

bool FITSFileName::ParseExt(const wxString& filename, wxString&basename, wxString &ext)
{
  // parse filenames and FITSIO's extended names file.fits[*]

  wxRegEx rf("([^[]+)(.*)");
  wxASSERT(rf.IsValid());
  if( rf.Matches(filename) ) {
    basename = rf.GetMatch(filename,1);
    ext = rf.GetMatch(filename,2);
    return true;
  }
  else {
    basename = filename;
    ext = "";
    return false;
  }



  /*

  One does't works: why?

  char *filetype =0,*infile=0,*outfile=0,*extspec=0,*filter=0,*binspec=0,
    *colspec=0,*pixspec=0;

  int status;
  status = 0;
  const char *dd = name.fn_str();
  fits_parse_input_filename((char*)dd,filetype,infile,outfile,
			    extspec,filter,binspec,colspec,pixspec,&status);

  wxLogDebug("%d %s %s %s %s "+name,(int)status,filetype,infile,outfile,dd);

  if( status == 0 )
    filename = outfile;
  else
    filename = name;
  */


}
