using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

using VirtualLab.Programming;
using VirtualLabAPI.Core.BasicFunctions;
using VirtualLabAPI.Core.Common;
using VirtualLabAPI.Core.DataVisualization;
using VirtualLabAPI.Core.FieldRepresentations;
using VirtualLabAPI.Core.Functions;
using VirtualLabAPI.Core.GeometryDescription;
using VirtualLabAPI.Core.LightPath;
using VirtualLabAPI.Core.Materials;
using VirtualLabAPI.Core.Modules;
using VirtualLabAPI.Core.Numerics;
using VirtualLabAPI.Core.Numerics.Region2D;
using VirtualLabAPI.Core.OpticalSystems;
using VirtualLabAPI.Core.Propagation;

namespace OwnCode {
    public class VLModule : IVLModule {
        public void Run() {
            
            // Read in fields (reference field and field for analysis): 
            ComplexAmplitude caReference = 
                (ComplexAmplitude) (VL_GUI.SelectOpenField("Select reference field"));
            ComplexAmplitude caAnalysis = 
                (ComplexAmplitude) (VL_GUI.SelectOpenField("Select field for analysis"));

            // Declare the outputs: 
            double relativeDeviation; 
            double absoluteDeviation; 
            Complex scalingFactor;
            
            // Compute deviation without scaling: 
            ComplexAmplitudeOperations.ComputeDeviation(
                caAnalysis, // Field to be analyzed. 
                caReference, // Reference field. 
                false, // Whether scaling shall be applied or not. 
                out relativeDeviation, // The resulting relative deviation (Eq. 1).
                out absoluteDeviation, // The resulting absolute deviation. 
                out scalingFactor, // The scaling factor (= 1 if without scaling).
                InterpolationMethod.Nearest); // Interpolation method employed to match the sampling 
            // of the two fields. 
            
            // Display results in Messages window using custom
            // support function (see below): 
            VL_GUI.WriteLineToMessagesTab("--Calculation WITHOUT scaling--");
            Display(scalingFactor, relativeDeviation, absoluteDeviation);
            
            // Compute deviation with scaling: 
            ComplexAmplitudeOperations.ComputeDeviation(
                caAnalysis, 
                caReference, 
                true, 
                out relativeDeviation, 
                out absoluteDeviation, 
                out scalingFactor, 
                InterpolationMethod.Nearest);
            
            // Display results in Messages window using 
            // custom support function (see below):
            VL_GUI.WriteLineToMessagesTab("--Calculation WITH scaling--");
            Display(scalingFactor, relativeDeviation, absoluteDeviation);
            
        }
        // For illustration purposes, we define a support function 
        // that delivers the values returned by the calculation to 
        // the Messages window
        public void Display(Complex ScalingFactor, double RelativeDeviation, double AbsoluteDeviation)
        {
            VL_GUI.WriteToMessagesTab("Scaling factor: " + ScalingFactor.ToString() + 
                "\nRelative deviation: " + RelativeDeviation.ToString() + 
                "\nAbsolute deviation: " + AbsoluteDeviation.ToString());
        }
    }
}