/*  FSLView - 2D/3D Interactive Image Viewer

    Authors:    Rama Aravind Vorray
		James Saunders
		David Flitney 
		Mark Jenkinson
		Stephen Smith

    FMRIB Image Analysis Group

    Copyright (C) 2002-2005 University of Oxford  */

/*  CCOPYRIGHT */

#include "preferences.h"
#include <stdlib.h>
#include <iostream>

#include <QtCore/QVariant>

using namespace std;

struct Preferences::Implementation
{
  Implementation() : m_assistantpath(""), m_atlaspath(""), 
		     m_fsldir(""), m_mni(""), m_w(0), m_h(0), m_x(0), m_y(0)
  {
  }
  
  string m_assistantpath;
  string m_atlaspath;
  string m_fsldir;
  string m_mni;
  int m_w, m_h, m_x, m_y;
};

Preferences::Handle Preferences::m_instance;

Preferences::Preferences(): m_impl(new Preferences::Implementation())
{
  bool ok;
  setPath("fmrib.ox.ac.uk", "fslview", QSettings::UserScope);

  if(m_impl->m_atlaspath == "") {
    QStringList l = readListEntry("/fsl/atlaspath", &ok);
    if(ok)
      m_impl->m_atlaspath = l.join(":").ascii();
  }
}

//! @brief Access Preferences singleton
//!
//! @return a handle to be used as a pointer to a Preferences object
Preferences::Handle Preferences::getInstance()
{
  if(!m_instance)
    m_instance = Preferences::Handle(new Preferences());

  return m_instance;
}

string Preferences::inqAtlasPath()
{
  // bool ok;
  // if(m_impl->m_atlaspath == "") {
  //   QStringList l = readListEntry("/fsl/atlaspath", &ok);
  //   if(ok)
  //     m_impl->m_atlaspath = l.join(":").ascii();
  // }

  if(m_impl->m_atlaspath == "")
    m_impl->m_atlaspath = string(getenv("FSLATLASPATH") ? 
				 getenv("FSLATLASPATH") :
				 inqFSLDir() + "/data/atlases");

  return m_impl->m_atlaspath;
}

//! @brief Prefered value for window geometry
//!
//! Returns prefered values from Qt prefs or heuristically determines
//! the default placement from passed in desktop width and height measures
//!
//! @param dw width of desktop
//! @param dh height of desktop
//!
//! @return QRect The require geometry
QRect Preferences::inqGeometry(int dw, int dh)
{
  QRect result;
    
  int x( readNumEntry("/fslview/geometry/x", -1) );
  int y( readNumEntry("/fslview/geometry/y", -1) );
  int w( readNumEntry("/fslview/geometry/width", -1) );
  int h( readNumEntry("/fslview/geometry/height", -1) );

  if( (x == -1) || (y == -1) || (w == -1) || (h == -1) ) {
    if(dh <= 800) {
      h = (dh * 85) / 100;
      w = (dw * 85) / 100;
      x = (dw - w)/2;
      y = (dh - h)/2;
    } else {
      h = (dh * 90) / 100;
      w = (h  * 80) / 100;
      x = y = (dh * 5) / 100;
    }
  }

  return QRect(x, y, w, h);
}

void Preferences::setGeometry(const QRect& r)
{
  writeEntry( "/fslview/geometry/x", r.x() );
  writeEntry( "/fslview/geometry/y", r.y() );
  writeEntry( "/fslview/geometry/width", r.width() );
  writeEntry( "/fslview/geometry/height", r.height() );
}

//! @brief Prefered value of FSLATLASPATH
//!
//! Returns vector of the prefered values of FSLATLASPATH or FSLDIR/lib/atlases
//!
//! @return The locations to look for atlas data sets
vector<string> Preferences::inqAtlasPathElements()
{
  vector<string> result;
  string delimiters(":");

  string str(inqAtlasPath());
  string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  string::size_type pos = str.find_first_of(delimiters, lastPos);

  while (string::npos != pos || string::npos != lastPos)
    {
      result.push_back( str.substr(lastPos, pos - lastPos) );
      lastPos = str.find_first_not_of(delimiters, pos);
      pos = str.find_first_of(delimiters, lastPos);
    }
  
  return result;
}
   
//! @brief Prefered value of FSLDIR
//!
//! Returns the prefered value of FSLDIR
//!
//! @return The users prefered value of FSLDIR
string Preferences::inqFSLDir()
{
  if(m_impl->m_fsldir == "")
    m_impl->m_fsldir = readEntry("/fsl/fsldir", "").ascii();
  if(m_impl->m_fsldir == "")
    m_impl->m_fsldir = string(getenv("FSLDIR") ? getenv("FSLDIR") : "/usr/local/fsl");

  return m_impl->m_fsldir; 
}

//! @brief Prefered location of MNI152 T1 brain
//!
//! Returns the prefered location where we can find MNI152 T1 brain image
//!
//! @return The users prefered location for the MNI152 T1 brain image
string Preferences::inqMni152()
{
  if(m_impl->m_mni == "")
    m_impl->m_mni = readEntry("/fsl/mni","").ascii();
  if(m_impl->m_mni == "")
    m_impl->m_mni = inqFSLDir() + "/data/standard/MNI152_T1_2mm_brain.nii.gz";

  return m_impl->m_mni;
}

string Preferences::inqAssistantPath()
{
  if(m_impl->m_assistantpath == "")
    m_impl->m_assistantpath = readEntry("/qt/assistantpath","").ascii();
  if(m_impl->m_assistantpath == "")
    m_impl->m_assistantpath = string(getenv("FSLQTASSISTANTPATH") ? 
				     getenv("FSLQTASSISTANTPATH") : "");
  if(m_impl->m_assistantpath == "")
    m_impl->m_assistantpath = string(getenv("QTDIR") ? 
				     string(getenv("QTDIR")) + "/bin" : 
				     inqFSLDir() + "/bin");
  
  return m_impl->m_assistantpath;
}

void Preferences::setFSLDir(const std::string& dir)
{
  m_impl->m_fsldir = dir;
  writeEntry("/fsl/fsldir", dir.c_str());
}

void Preferences::setMni152(const std::string& filename)
{
  m_impl->m_mni = filename;
  writeEntry("/fsl/mni", filename.c_str());
}

void Preferences::setAssistantPath(const std::string& path)
{
  m_impl->m_assistantpath = path;
  writeEntry("/qt/assistantpath", path.c_str());
}

void Preferences::setAtlasPath(const std::string& path)
{
  m_impl->m_atlaspath = path;
  writeEntry("/fsl/atlaspath", QStringList::split(":", path.c_str()));
}
