// UI.Properties.Directory.cs created with MonoDevelop
// User: klose at 12:47 10.02.2009
// CVS release: $Id: UI.Properties.Directory.cs,v 1.10 2011-04-19 12:36:59 klose Exp $
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2009  Thomas Klose, Hiperscan GmbH Dresden, Germany
//
//    This program 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.
//
//    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;

using Glade;

using Gtk;

using Hiperscan.QuickStep.Dialog;
using Hiperscan.QuickStep.IO;
using Hiperscan.QuickStep.Treeview;
using Hiperscan.SGS;
using Hiperscan.Spectroscopy;
using Hiperscan.Unix;


namespace Hiperscan.QuickStep
{

    public partial class UserInterface
    {
        [Widget] Gtk.Fixed property_directory_fixed = null;

        [Widget] Gtk.ComboBox associated_device_combo = null;
        [Widget] Gtk.ComboBox output_culture_combo    = null;
        [Widget] Gtk.ComboBox single_filetype_combo   = null;
        [Widget] Gtk.ComboBox stream_filetype_combo   = null;

        [Widget] Gtk.CheckButton auto_save_single_checkbutton = null;
        [Widget] Gtk.CheckButton auto_save_stream_checkbutton = null;
        [Widget] Gtk.CheckButton activate_dir_checkbutton     = null;

        [Widget] Gtk.Label output_culture_label  = null;
        [Widget] Gtk.Label single_filemask_label = null;
        [Widget] Gtk.Label stream_filemask_label = null;

        [Widget] Gtk.Entry single_filemask_entry = null;
        [Widget] Gtk.Entry stream_filemask_entry = null;

        [Widget] Gtk.Button show_associated_device_button   = null;
        [Widget] Gtk.Button directory_property_apply_button = null;

        [Widget] Gtk.Frame spectrum_comment_frame = null;

        [Widget] Gtk.TextView spectrum_comment_text = null;

        DirectoryProperty current_directory_config = null;


        private void InitializePropertiesDirectory()
        {
            this.spectrum_comment_text.Buffer.Changed += this.OnDirectoryPropertyChanged;
            this.UpdatePropertiesDirectory(null);
        }

        private void UpdatePropertiesDirectory(DirectoryProperty dir)
        {
            if (this.property_notebook.Page != 1)
                return;

            if (dir == null)
            {
                this.property_directory_fixed.Sensitive = false;
                return;
            }

            this.current_object_label.Text = $"({dir.Info.FullName})";

            this.property_directory_fixed.Sensitive = true;

            ListStore store = new ListStore(typeof(string));
            CellRendererText text = new CellRendererText();

            this.associated_device_combo.Clear();
            this.associated_device_combo.PackStart(text, false);
            this.associated_device_combo.SetAttributes(text, "text", 0);
            this.associated_device_combo.Model = store;
            this.associated_device_combo.AppendText(Catalog.GetString("None"));

            int device_ix = 0;
            int ix = 0;

            foreach (IDevice dev in this.DeviceList.Values)
            {
                ++ix;

                this.associated_device_combo.AppendText(dev.CurrentConfig.Name);

                if (dev == dir.AssociatedDevice)
                    device_ix = ix;
            }

            this.associated_device_combo.Active = device_ix;
            this.output_culture_combo.Active = (int)dir.OutputCulture;

            this.activate_dir_checkbutton.Active = dir.Active;

            this.auto_save_single_checkbutton.Active = dir.AutoSaveSingle;
            this.single_filemask_entry.Text = dir.SingleFilemask;
            this.single_filetype_combo.Active = (int)dir.SingleFiletype;

            this.auto_save_stream_checkbutton.Active = dir.AutoSaveStream;
            this.stream_filemask_entry.Text = dir.StreamFilemask;
            this.stream_filetype_combo.Active = (int)dir.StreamFiletype;

            //this.spectrum_comment_text.Buffer.Clear();
            this.spectrum_comment_text.Buffer.Text = dir.SpectrumComment;

            this.PropertiesDirectorySetSensitive();

            this.directory_property_apply_button.Sensitive = false;

            this.current_directory_config = dir;
        }

        private void PropertiesDirectorySetSensitive()
        {
            int device_ix = this.associated_device_combo.Active;
            bool sensitive = (device_ix != 0);

            string choice = this.associated_device_combo.ActiveText;

            this.show_associated_device_button.Sensitive = 
                sensitive && 
                (this.current_directory_config.AssociatedDevice == this.DeviceList.GetByName(choice));

            this.activate_dir_checkbutton.Sensitive = sensitive;

            this.output_culture_label.Sensitive = sensitive;
            this.output_culture_combo.Sensitive = sensitive;

            this.auto_save_single_checkbutton.Sensitive = sensitive;
            this.auto_save_stream_checkbutton.Sensitive = sensitive;

            bool single = sensitive && this.auto_save_single_checkbutton.Active;
            this.single_filemask_label.Sensitive = single;
            this.single_filemask_entry.Sensitive = single;
            this.single_filetype_combo.Sensitive = single;

            bool stream = sensitive && this.auto_save_stream_checkbutton.Active;
            this.stream_filemask_label.Sensitive = stream;
            this.stream_filemask_entry.Sensitive = stream;
            this.stream_filetype_combo.Sensitive = stream;

            this.spectrum_comment_frame.Sensitive = single || stream;
        }

        private List<DirectoryProperty> GetAssociatedDirectories(IDevice dev)
        {
            var list = new List<DirectoryProperty>();

            if (dev == null)
                return list;

            foreach (Widget w in this.file_notebook.Children)
            {
                ScrolledFileTv tv = w as ScrolledFileTv;

                foreach (DirectoryProperty dp in tv.GetDirectoryProperties())
                {
                    if (dp.AssociatedDevice != null &&
                        dp.AssociatedDevice.Info.SerialNumber == dev.Info.SerialNumber)
                    {
                        list.Add(dp);
                    }
                }
            }

            list.Sort();

            return list;
        }

        private void ShowDirectoryProperty(DirectoryProperty dp)
        {
            if (dp == null)
                return;

            bool found = false;
            int page;

            for (page = 0; page < this.file_notebook.Children.Length; ++page)
            {
                ScrolledFileTv tv = this.file_notebook.Children[page] as ScrolledFileTv;

                if (tv.SelectDirectory(dp))
                {
                    found = true;
                    break;
                }
            }

            if (!found)
                return;

            this.file_notebook.CurrentPage = page;

            this.UpdatePropertiesDirectory(dp);
            this.PropertyType = Config.PropertyType.Directory;
        }

        internal void OnAssociatedDeviceComboChanged(object o, EventArgs e)
        {
            this.PropertiesDirectorySetSensitive();
            this.directory_property_apply_button.Sensitive = true;
        }

        internal void OnDirectoryPropertyChanged(object o, EventArgs e)
        {
            this.directory_property_apply_button.Sensitive = true;
        }

        internal void OnShowAssociatedDeviceButtonClicked(object o, EventArgs e)
        {
            this.spectrometer_tv.SelectDevice(this.current_directory_config.AssociatedDevice);
        }

        internal void OnActivateDirCheckbuttonToggled(object o, EventArgs e)
        {
            this.PropertiesDirectorySetSensitive();
            this.directory_property_apply_button.Sensitive = true;
        }

        internal void OnAutoSaveSingleCheckbuttonToggled(object o, EventArgs e)
        {
            this.PropertiesDirectorySetSensitive();
            this.directory_property_apply_button.Sensitive = true;
        }

        internal void OnAutoSaveStreamCheckbuttonToggled(object o, EventArgs e)
        {
            this.PropertiesDirectorySetSensitive();
            this.directory_property_apply_button.Sensitive = true;
        }

        internal void OnDirectoryPropertyApplyButtonClicked(object o, EventArgs e)
        {
            string choice = this.associated_device_combo.ActiveText;

            if (this.DeviceList.ContainsName(choice))
            {
                // check filemasks
                try
                {
                    DirectoryProperty.AssembleFilename(this.current_directory_config.Info.FullName,
                                                       new Spectrum(WavelengthLimits.DefaultWavelengthLimits),
                                                       this.single_filemask_entry.Text,
                                                       ".csv");
                }
                catch (Exception ex)
                {
                    InfoMessageDialog.Show(this.MainWindow,
                                     Catalog.GetString("Cannot parse filename mask for single spectra: {0}"),
                                     ex.Message);
                    return;
                }

                try
                {
                    DirectoryProperty.AssembleFilename(this.current_directory_config.Info.FullName,
                                                       new Spectrum(WavelengthLimits.DefaultWavelengthLimits),
                                                       this.stream_filemask_entry.Text, 
                                                       ".csv");
                }
                catch (Exception ex)
                {
                    InfoMessageDialog.Show(this.MainWindow,
                                     Catalog.GetString("Cannot parse filename mask for stream spectra: {0}"),
                                     ex.Message);
                    return;
                }

                UserInterface.Settings.Current.SingleFileMask = this.single_filemask_entry.Text;
                UserInterface.Settings.Current.StreamFileMask = this.stream_filemask_entry.Text;

                this.current_directory_config.Active = this.activate_dir_checkbutton.Active;

                this.current_directory_config.AssociatedDevice = this.DeviceList.GetByName(choice);
                this.current_directory_config.AutoSaveSingle   = this.auto_save_single_checkbutton.Active;
                this.current_directory_config.AutoSaveStream   = this.auto_save_stream_checkbutton.Active;

                this.current_directory_config.OutputCulture = (OutputCulture)this.output_culture_combo.Active;

                this.current_directory_config.SingleFilemask = this.single_filemask_entry.Text;
                this.current_directory_config.SingleFiletype = (SpectrumFileType)this.single_filetype_combo.Active;

                this.current_directory_config.StreamFilemask = this.stream_filemask_entry.Text;
                this.current_directory_config.StreamFiletype = (SpectrumFileType)this.stream_filetype_combo.Active;

                this.current_directory_config.SpectrumComment = this.spectrum_comment_text.Buffer.Text;
            }
            else
            {
                this.current_directory_config.AssociatedDevice = null;
            }

            this.PropertiesDirectorySetSensitive();

            this.directory_property_apply_button.Sensitive = false;
        }

        private void OnFileTvDirectoryDoubleClicked(DirectoryProperty dir)
        {
            this.PropertyType = Config.PropertyType.Directory;
            this.PropertyEditorVisible = true;
        }

        private void OnFileTvDirectorySelectionChanged(List<DirectoryProperty> selected_dirs)
        {
            this.PropertyType = Config.PropertyType.Directory;

            if (selected_dirs.Count == 0)
            {
                this.UpdatePropertiesDirectory(null);
                return;
            }

            this.UpdatePropertiesDirectory(selected_dirs[0]);
        }

        internal void OnAdditionalDataClicked(object o, System.EventArgs e)
        {
            var d = new ExtractedDataDialog(this.MainWindow, this, this.current_directory_config.Info);
        }

        internal void OnBrowseDirClicked(object o, System.EventArgs e)
        {
            UserInterface.OpenFileBrowser(this.MainWindow, this.current_directory_config.Info.FullName);
        }
    }
}