// Created with MonoDevelop
//
//    Copyright (C) 2008 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 Hiperscan.Unix;


namespace Hiperscan.Spectroscopy
{

    public partial class DataSet
    {

        public static DataSet operator*(DataSet lhs, DataSet.Operand rhs)
        {
            DataSet ds = new DataSet(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                ds.Add( lhs.X[ix] * rhs.XOperand, lhs.Y[ix] * rhs.YOperand );
            }
            return ds;
        }
        
        public static DataSet operator*(DataSet lhs, DataSet rhs)
        {
            if (lhs.Count != rhs.Count)
                throw new ArgumentException(Catalog.GetString("Multiplied data sets must have the same length.") +
                                            string.Format("lhs.Count={0}, rhs.Count={1}", lhs.Count, rhs.Count));

            List<double> y = new List<double>(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                y.Add(lhs.Y[ix] * rhs.Y[ix]);
            }
            return new DataSet(new List<double>(lhs.X), y);            
        }

        public static DataSet operator/(DataSet lhs, DataSet.Operand rhs)
        {
            DataSet ds = new DataSet(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                ds.Add( lhs.X[ix] / rhs.XOperand, lhs.Y[ix] / rhs.YOperand );
            }
            return ds;
        }
        
        public static DataSet operator/(DataSet lhs, DataSet rhs)
        {
            if (lhs.Count != rhs.Count)
                throw new ArgumentException(Catalog.GetString("Divided data sets must have the same length."));
            
            List<double> y = new List<double>(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                y.Add(lhs.Y[ix] / rhs.Y[ix]);
            }
            return new DataSet(new List<double>(lhs.X), y);            
        }

        public static DataSet operator+(DataSet lhs, DataSet.Operand rhs)
        {
            DataSet ds = new DataSet(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                ds.Add( lhs.X[ix] + rhs.XOperand, lhs.Y[ix] + rhs.YOperand );
            }
            return ds;
        }
        
        public static DataSet operator+(DataSet lhs, DataSet rhs)
        {
            if (lhs.Count != rhs.Count)
                throw new ArgumentException(Catalog.GetString("Added data sets must have the same length."));
            
            List<double> y = new List<double>(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                y.Add(lhs.Y[ix] + rhs.Y[ix]);
            }
            return new DataSet(new List<double>(lhs.X), y);    
        }
        
        public static DataSet operator-(DataSet lhs, DataSet.Operand rhs)
        {
            DataSet ds = new DataSet(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                ds.Add( lhs.X[ix] - rhs.XOperand, lhs.Y[ix] - rhs.YOperand );
            }
            return ds;
        }
        
        public static DataSet operator-(DataSet lhs, DataSet rhs)
        {
            if (lhs.Count != rhs.Count)
                throw new ArgumentException(Catalog.GetString("Subtracted data sets must have the same length."));
            
            List<double> y = new List<double>(lhs.Count);
            for (int ix=0; ix < lhs.Count; ++ix)
            {
                y.Add(lhs.Y[ix] - rhs.Y[ix]);
            }
            return new DataSet(new List<double>(lhs.X), y);            
        }
        
        public static DataSet operator+(DataSet lhs, double rhs)
        {
            return lhs + new DataSet.Operand(0.0, rhs);
        }

        public static DataSet operator+(double lhs, DataSet rhs)
        {
            return rhs + new DataSet.Operand(0.0, lhs);
        }

        public static DataSet operator-(DataSet lhs, double rhs)
        {
            return lhs - new DataSet.Operand(0.0, rhs);
        }

        public static DataSet operator-(double lhs, DataSet rhs)
        {
            return (rhs * new DataSet.Operand(1.0, -1.0)) + new DataSet.Operand(0.0, lhs);
        }

        public static DataSet operator*(DataSet lhs, double rhs)
        {
            return lhs * new DataSet.Operand(1.0, rhs);
        }

        public static DataSet operator*(double lhs, DataSet rhs)
        {
            return rhs * new DataSet.Operand(1.0, lhs);
        }

        public static DataSet operator/(DataSet lhs, double rhs)
        {
            return lhs / new DataSet.Operand(1.0, rhs);
        }

        public static DataSet operator/(double lhs, DataSet rhs)
        {
            DataSet ds = new DataSet(rhs.Count);
            for (int ix=0; ix < rhs.Count; ++ix)
            {
                ds.Add( rhs.X[ix], lhs / rhs.Y[ix] );
            }
            return ds;
        }
    }
}
