/*
 *  
 *  $Id: panelconfiguraciongeneral.cpp $
 *  Ginkgo CADx Project
 *
 *  Copyright 2008-12 MetaEmotion S.L. All rights reserved.
 *  http://ginkgo-cadx.com
 *
 *  This file is licensed under LGPL v3 license.
 *  See License.txt for details
 *
 *
 */
#include <vector>

#include <wx/checkbox.h>
#include <wx/msgdlg.h>
#include <wx/msgout.h>
#include <wx/dirdlg.h>
#include <wx/filename.h>
#include <wx/wxhttpengine/proxysettingsdlg.h>
#include <main/controllers/configurationcontroller.h>
#include <sstream>
#include <wx/file.h>
#include <wx/dir.h>
#include <wx/stdpaths.h>
#include <wx/xml/xml.h>

#include <wx/ginkgostyle/ginkgostyle.h>

#include "panelconfiguraciongeneral.h"

#include <main/controllers/controladorextensiones.h>
#include <main/controllers/controladoreventos.h>
#include <main/controllers/controladorvistas.h>
#include <main/controllers/controladorcomandos.h>
#include <main/controllers/historycontroller.h>
#include <main/gui/history3/historypanel3.h>
#include <main/entorno.h>
#include <api/controllers/icontroladorinternacionalizacion.h>
#include <api/internationalization/internationalization.h>

namespace GNC {
	namespace GUI {

		PanelConfiguracionGeneral::PanelConfiguracionGeneral(wxWindow* pParent,IDialogoConfiguracion* pDialogo): PanelConfiguracionGeneralBase(pParent), IPasoConfiguracion(pDialogo)
		{			
			pProxySettings = new wxProxySettings();
			if (GNC::GCS::ControladorVistas::Instance()->GetVistas().size() > 0)
			{
				m_pPanelDicomDir->Enable(false);
				m_pstaticTextAdvertencia->Show(true);
			}
			else
			{
				m_pstaticTextAdvertencia->Show(false);
			}
			m_idiomaCambiado = false;
			Recargar();
			Layout();
		}

		PanelConfiguracionGeneral::~PanelConfiguracionGeneral()
		{
			delete pProxySettings;
		}

		void PanelConfiguracionGeneral::Recargar()
		{
			std::string dicomDir;
			
			if(!GNC::GCS::ConfigurationController::Instance()->readStringUser("/GinkgoCore/Estacion","DicomDir", dicomDir)) {
				m_pathDicomDir = FROMPATH(GNC::GCS::HistoryController::Instance()->GetGinkgoDicomDir());
			} else {
				m_pathDicomDir = wxString::FromUTF8(dicomDir.c_str());
			}
			m_pDICOMDir->SetValue(m_pathDicomDir);

			//check for updates
			bool check;
			GNC::GCS::ConfigurationController::Instance()->readBoolGeneral("/GinkgoCore/Estacion", "CheckForUpdates", check, true);
			m_pCheckForUpdates->SetValue(check);

			
			//internacionalizacion
			int language;
			GNC::GCS::ConfigurationController::Instance()->readIntUser("/GinkgoCore/Station", "Language", language);

			//explore lang directory to find installed languages
			{
				m_pComboLanguage->Clear();
				m_mapLanguages.clear();
				m_mapLanguages[_Std("Default")] = -1;
				m_mapLanguages["English"] = (int)wxLANGUAGE_ENGLISH;
				wxString wxDirPath = FROMPATH(GNC::Entorno::Instance()->GetGinkgoLanguageDir());
				wxDir dir;
				if (dir.Open(wxDirPath)) {
					wxString wxPathLang;
					bool cont = dir.GetFirst(&wxPathLang,wxEmptyString, wxDIR_DIRS);
					while (cont) {
						const wxLanguageInfo* pInfo = wxLocale::FindLanguageInfo(wxPathLang);
						if (pInfo != NULL) {
							m_mapLanguages[std::string(pInfo->Description.ToUTF8())] = pInfo->Language;
						}
						cont = dir.GetNext(&wxPathLang);
					}
				}
				for (TMapLanguages::iterator it  = m_mapLanguages.begin(); it != m_mapLanguages.end(); ++it) {
					int position = m_pComboLanguage->Append(wxString::FromUTF8((*it).first.c_str()));
					if ((*it).second == language) {
						m_pComboLanguage->Select(position);
					}
				}
				if (m_pComboLanguage->GetSelection() == -1) {
					m_pComboLanguage->Select(m_pComboLanguage->FindString(_("Default")));
				}
			}

			//proxy Settings
			{
				pProxySettings->ProxySettingsLoadGeneral();
				m_pEnableProxy->SetValue(pProxySettings->m_bUseProxy);
				m_pProxySettingsButton->Enable(pProxySettings->m_bUseProxy);
			}
		}

		//region "Metodos de IPasoConfiguracion"
		wxWindow* PanelConfiguracionGeneral::GetPanel()
		{
			return this;
		}

		std::string PanelConfiguracionGeneral::GetTitle()
		{
			return _Std("General");
		}

		std::string PanelConfiguracionGeneral::GetCabecera()
		{
			return _Std("General configuration parameters");
		}

		bool PanelConfiguracionGeneral::Validar()
		{
			wxString path = m_pDICOMDir->GetValue();
			wxFileName fileName(path);
			if(!fileName.IsAbsolute()) {
				wxFileName pathOfExec(wxStandardPaths::Get().GetExecutablePath());
				fileName.MakeAbsolute(pathOfExec.GetPath());
				path = fileName.GetFullPath();
			}

			if(!wxDir::Exists(path)) {
				//se pregunta si desea crearlo
				int answer = wxMessageBox(_("The selected directory does not exist\nWould you like to create it?"),_("Info"),wxYES_NO,this);
				if(answer == wxNO) {
					return false;
				} else {
		#ifdef _WIN32
					wxMkdir(path,511);
		#else
					wxMkDir(path.ToUTF8(), 0770);
		#endif
					if(!wxDirExists(path))
					{
						wxMessageBox(_("Failed to create directory, make sure the path is correct and you have permissions on parent directory"), _("Info"));
						return false;
					}
				}
			} else {
				//se comprueba que puede escribir(escribimos y borramos un fichero chorra)
				wxString pathFicheroPrueba = path + wxFileName::GetPathSeparator() + wxString::Format(wxT("%d"),rand());
				while(wxFileExists(pathFicheroPrueba)) {
					pathFicheroPrueba = path + wxFileName::GetPathSeparator() + wxString::Format(wxT("%d"),rand());
				}
				{
					wxFile ficheroTmp;
					if(!ficheroTmp.Create(pathFicheroPrueba,false)){
						if(!wxFileExists(pathFicheroPrueba) ) {
							wxMessageBox(_("There was an error reading the directory, make sure you have write permissions on it"), _("Info"));
								return false;
						}
					}
					ficheroTmp.Write(wxT("prueba"));
					ficheroTmp.Close();
				}
				wxRemoveFile(pathFicheroPrueba);
			}

			if(m_idiomaCambiado) {
				wxMessageBox(_("Ginkgo CADx must restart for the changes to take effect"),_("Info"));
			}

			return true;
		}

		bool PanelConfiguracionGeneral::Guardar()
		{
			//se actualiza el fichero de configuracion
			wxFileName dirAnterior(m_pathDicomDir);
			wxFileName dirNuevo(m_pDICOMDir->GetValue());
			if(dirAnterior != dirNuevo)
			{
				GNC::GCS::ConfigurationController::Instance()->writeStringUser("/GinkgoCore/Estacion", "DicomDir",std::string(m_pDICOMDir->GetValue().ToUTF8()));
				//se vacia el dicomdir actual y se carga el nuevo...
				GNC::GCS::HistoryController::FreeInstance();
				if (!GNC::GCS::HistoryController::Instance()->IsOk()) {
					//revert changes....
					GNC::GCS::ConfigurationController::Instance()->writeStringUser("/GinkgoCore/Estacion", "DicomDir", std::string(m_pathDicomDir.ToUTF8()));
					//se vacia el dicomdir actual y se carga el nuevo...
					GNC::GCS::HistoryController::FreeInstance();
				}
				GNC::GUI::HistoryPanel3::Instance()->ReloadHistory();
				
			}

			GNC::GCS::ConfigurationController::Instance()->writeBoolGeneral("/GinkgoCore/Estacion", "CheckForUpdates", m_pCheckForUpdates->GetValue());

			//internacionalizacion			
			if (m_pComboLanguage->GetStringSelection() != _("Default")) {
				std::string selectedLanguage(m_pComboLanguage->GetStringSelection().ToUTF8());
				for (TMapLanguages::iterator it  = m_mapLanguages.begin(); it != m_mapLanguages.end(); ++it) {
					if ((*it).first == selectedLanguage) {
						GNC::GCS::ConfigurationController::Instance()->writeIntUser("/GinkgoCore/Station", "Language", (*it).second);
						break;
					}
				}
			} else {
				GNC::GCS::ConfigurationController::Instance()->deleteEntryUser("/GinkgoCore/Station", "Language");
			}
			//proxy
			pProxySettings->ProxySettingsSaveGeneral();

			return true;
		}
		//endregion

		void PanelConfiguracionGeneral::OnCheckForUpdates(wxCommandEvent &)
		{
			if(IsShown()){
				OnPropiedadCambiada();
			}
		}


		void PanelConfiguracionGeneral::OnTextoCambiado(wxCommandEvent &)
		{
			if(IsShown()){
				OnPropiedadCambiada();
			}
		}

		void PanelConfiguracionGeneral::OnIdiomaCambiado(wxCommandEvent &)
		{
			if(IsShown()){
				OnPropiedadCambiada();
				m_idiomaCambiado = true;
			}
		}

		
		void PanelConfiguracionGeneral::OnSeleccionarDirectorio(wxCommandEvent &)
		{
			wxDirDialog seleccionarDirectorio(this,_("Select DICOMDIR"),m_pDICOMDir->GetValue(),wxDD_DEFAULT_STYLE|wxDD_NEW_DIR_BUTTON);
			int response = seleccionarDirectorio.ShowModal();
			if (response == wxID_OK)
			{
				m_pDICOMDir->SetValue(seleccionarDirectorio.GetPath());
			}
		}

		void PanelConfiguracionGeneral::OnSize(wxSizeEvent & event){
			wxSize oldSize = m_pstaticTextAdvertencia->GetSize();
			Freeze();
			m_pstaticTextAdvertencia->Freeze();
			m_pstaticTextAdvertencia->SetLabel(_("Warning, to update the directory, you must close current opened series."));
			m_pstaticTextAdvertencia->Wrap( event.GetSize().x - 25 );
			m_pstaticTextAdvertencia->Thaw();
			Thaw();
			wxSize newSize = m_pstaticTextAdvertencia->GetSize();
			if (newSize != oldSize) {
				Layout();
				event.Skip(false);
			} else {
				event.Skip(true);
			}
		}
		
		void PanelConfiguracionGeneral::OnProxySettings(wxCommandEvent &)
		{
			wxProxySettingsDlg dlg(this, wxID_ANY);
			dlg.SetProxySettings(*pProxySettings);
			if (dlg.ShowModal() == wxID_OK) {
				(*pProxySettings) = dlg.GetProxySettings();
				OnPropiedadCambiada();
			}
		}

		void PanelConfiguracionGeneral::OnCheckEnableProxySettings(wxCommandEvent &)
		{
			m_pProxySettingsButton->Enable(m_pEnableProxy->IsChecked());
			pProxySettings->SetUseProxy(m_pEnableProxy->IsChecked());
			OnPropiedadCambiada();
		}
	}
}
