// Created with MonoDevelop
//
//    Copyright (C) 2009 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.Drawing;


namespace Hiperscan.Spectroscopy
{

    public partial class Spectrum
    {
        public bool HasReference
        {
            get { return this.reference != null; }
        }

        public bool HasAbsorbance
        {
            get
            {
                if (this.absorbance == null || this.absorbance_limit == null)
                    this.UpdateAbsorbance();
                return this.absorbance != null && this.absorbance_limit != null;
            }
        }

        public bool HasReflectance
        {
            get
            {
                if (this.reflectance == null)
                    this.UpdateReflectance();
                return this.reflectance != null;
            }
        }

        public bool HasDarkIntensity
        {
            get { return this.DarkIntensity.Intensity.Equals(0.0) == false; }
        }

        public bool HasWavelengthCorrection
        {
            get { return this.wavelength_correction != null; }
        }

        public bool HasWavelengthLimits
        {
            get { return this.wavelength_limits != null; }
        }

        public bool HasAdcCorrection
        {
            get { return this.adc_correction != null; }
        }

        public bool HasSystemFunctionCorrection
        {
            get { return this.system_function_correction != null; }
        }

        public bool HasLinearDistortion
        {
            get { return this.linear_distortion != null; }
        }

        public bool HasAddData
        {
            get { return this.AddData != null && this.AddData.Length > 0; }
        }

        public DataSet RawIntensity
        {
            get { return this.raw_intensity; }
            set
            {
                this.raw_intensity = value;
                this.raw_intensity.Id = this.Id;
                this.raw_intensity.Label = this.Label;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public Spectrum Reference
        {
            get { return this.reference; }
            set
            {
                if (value != null)
                {
                    this.reference = new Spectrum(value)
                    {
                        Id = this.Id,
                        Label = this.Label
                    };
                    if (this.HasDarkIntensity && !this.reference.HasDarkIntensity)
                        this.reference.DarkIntensity = this.DarkIntensity;
                    if (this.HasLinearDistortion && !this.reference.HasLinearDistortion)
                        this.reference.LinearDistortion = this.LinearDistortion;
                    this.reference.LimitBandwidth = this.LimitBandwidth;
                }
                else
                {
                    this.reference = null;
                }
                this.absorbance = null;
                this.absorbance_limit = null;
                this.reflectance = null;
            }
        }

        public DataSet Intensity
        {
            get
            {
                if (this._intensity == null)
                {
                    DataSet ds = this.GetCorrectedRawIntensity(CorrectionMask.All, this.LimitBandwidth);
                    ds.DataType = DataType.Intensity;
                    ds.Label = this.Label;
                    ds.Id = this.Id;

                    if (this.HasDarkIntensity)
                        ds -= this.GetCorrectedDarkIntensity(CorrectionMask.All).Intensity;

                    this._intensity = ds;
                }
                return this._intensity;
            }
        }

        public DarkIntensity DarkIntensity
        {
            get { return this.dark_intensity; }
            set
            {
                this.dark_intensity = value;
                if (this.HasReference)
                    this.Reference.DarkIntensity = value;
                this._intensity = null;
                this.absorbance = null;
                this.absorbance_limit = null;
                this.reflectance = null;
            }
        }

        public WavelengthCorrection WavelengthCorrection
        {
            get { return this.wavelength_correction; }
            set
            {
                this.wavelength_correction = value;
                if (this.HasReference)
                    this.Reference.WavelengthCorrection = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public WavelengthLimits WavelengthLimits
        {
            get { return this.wavelength_limits; }
            set
            {
                this.wavelength_limits = value;
                if (this.HasReference)
                    this.Reference.WavelengthLimits = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public DataSet AdcCorrection
        {
            get { return this.adc_correction; }
            set
            {
                if (this.adc_correction == value)
                    return;
                this.adc_correction = value;
                if (this.HasReference)
                    this.Reference.AdcCorrection = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public double[] SystemFunctionCorrection
        {
            get { return this.system_function_correction; }
            set
            {
                if (this.system_function_correction != null &&
                    this.system_function_correction.GetHashCode() == value.GetHashCode())
                    return;
                this.system_function_correction = value;
                if (this.HasReference)
                    this.Reference.SystemFunctionCorrection = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public LinearDistortion LinearDistortion
        {
            get { return this.linear_distortion; }
            set
            {
                if (this.linear_distortion == value)
                    return;
                this.linear_distortion = value;
                if (this.HasReference)
                    this.Reference.LinearDistortion = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public DataSet Absorbance
        {
            get
            {
                if (this.absorbance == null)
                    this.UpdateAbsorbance();
                return this.absorbance;
            }
        }

        public double AbsorbanceLimit
        {
            get
            {
                if (this.absorbance_limit == null)
                    this.UpdateAbsorbance();
                return (double)this.absorbance_limit;
            }
        }

        public DataSet Reflectance
        {
            get
            {
                if (this.reflectance == null)
                    this.UpdateReflectance();
                return this.reflectance;
            }
        }

        public string Id
        {
            get { return this.id; }
            set
            {
                this.id = value;
                this.RawIntensity.Id = value;

                if (this._intensity != null)
                    this._intensity.Id = value;
                if (this.HasReference)
                    this.reference.Id = value;
                if (this.HasAbsorbance)
                    this.absorbance.Id = value;
                if (this.HasReflectance)
                    this.reflectance.Id = value;
            }
        }

        public string Label
        {
            get { return this.label; }
            set
            {
                string l = value.Replace("\n", " ");
                this.label = l;
                this.RawIntensity.Label = l;

                if (this._intensity != null)
                    this._intensity.Label = l;
                if (this.HasReference)
                    this.reference.Label = l;
                if (this.HasAbsorbance)
                    this.absorbance.Label = l;

                this.DefaultLabel = false;
            }
        }

        public int Count
        {
            get { return this.RawIntensity.Count; }
        }

        public bool LimitBandwidth
        {
            get { return this.limit_bandwidth; }
            set
            {
                if (value == this.limit_bandwidth)
                    return;
                this.limit_bandwidth = value;
                if (this.HasReference)
                    this.Reference.LimitBandwidth = value;
                this._intensity = null;
                this.absorbance = null;
                this.reflectance = null;
            }
        }

        public bool IsPreview
        {
            get { return this.Id == "9_preview"; }
        }

        public bool IsStream
        {
            get { return this.SpectrumType == SpectrumType.Stream || this.SpectrumType == SpectrumType.QuickStream; }
        }

        public Color Color
        {
            get { return this.color; }
            set
            {
                this.color = value;
                this.RawIntensity.Color = value;

                if (this._intensity != null)
                    this._intensity.Color = value;
                if (this.HasReference)
                    this.reference.Color = value;
                if (this.HasAbsorbance)
                    this.absorbance.Color = value;
                if (this.HasReflectance)
                    this.reflectance.Color = value;

                this.DefaultStyle = false;
            }
        }

        public float LineWidth
        {
            get { return this.line_width; }
            set
            {
                this.line_width = value;
                this.RawIntensity.LineWidth = value;

                if (this._intensity != null)
                    this._intensity.LineWidth = value;
                if (this.HasReference)
                    this.reference.LineWidth = value;
                if (this.HasAbsorbance)
                    this.absorbance.LineWidth = value;
                if (this.HasReflectance)
                    this.reflectance.LineWidth = value;

                this.DefaultStyle = false;
            }
        }

        public LineStyle LineStyle
        {
            get { return this.line_style; }
            set
            {
                this.line_style = value;
                this.RawIntensity.LineStyle = value;

                if (this._intensity != null)
                    this._intensity.LineStyle = value;
                if (this.HasReference)
                    this.reference.LineStyle = value;
                if (this.HasAbsorbance)
                    this.absorbance.LineStyle = value;
                if (this.HasReflectance)
                    this.reflectance.LineStyle = value;

                this.DefaultStyle = false;
            }
        }

        public MarkerStyle MarkerStyle
        {
            get { return this.marker_style; }
            set
            {
                this.marker_style = value;
                this.RawIntensity.MarkerStyle = value;

                if (this._intensity != null)
                    this._intensity.MarkerStyle = value;
                if (this.HasReference)
                    this.reference.MarkerStyle = value;
                if (this.HasAbsorbance)
                    this.absorbance.MarkerStyle = value;
                if (this.HasReflectance)
                    this.reflectance.MarkerStyle = value;

                this.DefaultStyle = false;
            }
        }

        public int ZOrder
        {
            get { return this.z_order; }
            set
            {
                this.z_order = value;
                this.RawIntensity.ZOrder = value;

                if (this._intensity != null)
                    this._intensity.ZOrder = value;
                if (this.HasReference)
                    this.reference.ZOrder = value;
                if (this.HasAbsorbance)
                    this.absorbance.ZOrder = value;
                if (this.HasReflectance)
                    this.reflectance.ZOrder = value;
            }
        }
    }
}
