//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.8670
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace WComp.Beans
{
    using System;
    using WComp.Beans;
    using System.Collections.Generic;
    using System.Globalization;
    
    [Bean(Category="Manchon_services")]
    public class CSVExporter
    {
        #region Property SaveFile
        private string _savefile;
        public string SaveFile
        {
            get
            {
                return _savefile;
            }
            set
            {
                _savefile = value;
            }
        }
        #endregion
                
        #region Property WaterLitrePrice
        private float _waterLitrePrice;
        public float WaterLitrePrice
        {
            get
            {
                return _waterLitrePrice;
            }
            set
            {
                _waterLitrePrice = value;
            }
        }
        #endregion
        
        #region attributes
        private bool showerStatus = false;
        private List<double> data;
        private double timestamp;
        #endregion
        
        /// <summary>
        /// Link this event to the shower's status. 
        /// On falling edge, a new CSV file is created and the data is flushed to it. No further saving of data occurs.
        /// On rising edge, data recording and buffering starts.
        /// </summary>
        /// <param name="status"></param>
        public void SetShowerStatus(bool status) {
        	// Skip doubled events
        	if(status == showerStatus) return;
        	
        	if(status){
        		// Initialize logging
        		data = new List<double>();
        		
        		// Time
        		timestamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
        	} else {
        		// Calculate shower length
        		double showerLength = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - timestamp;
        		
        		// Calculate water used
        		double waterUsed = calculateAverageRate() * (showerLength / 1000);
        		
        		// Write to file
        		try{
        			// File format:
        			// date,length,water used,money spent
        			System.IO.File.AppendAllText(SaveFile, 
        				DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "," +
        				showerLength / 1000 + "," +
        				waterUsed + "," +
        				WaterLitrePrice * waterUsed + "\r\n"
        			);
        		} catch(Exception e){
        			Console.WriteLine("Saving to file failed with exception");
        			Console.WriteLine(e.ToString());
        		}
        		
        		// Turn off logging
        		data = null;
        		
        		// Fire events
        		FireFileSavedEvent();
        	}
        	
        	// Store the new status
        	showerStatus = status;
        }
        
        /// <summary>
        /// Link this event the shower's water flow event.
        /// It buffers the data until the shower is turned off.
        /// </summary>
        /// <param name="value"></param>
        public void WaterInput(string value) {
        	if(data != null){
        		data.Add(double.Parse(value, CultureInfo.InvariantCulture));
        		FireWaterVolumeChangedEvent();
        	}
        }
        
        private double calculateAverageRate(){
        	float w = 0;
        	foreach(float i in data){
        		w+=i;
        	}
        	return w/data.Count;
        }
        
        #region test event
        public delegate void TestEventHandler(string value);
        public event TestEventHandler Test;
        private void FireTestEvent(string value)
        {
            if (Test != null)
            {
                this.Test(value);
            }
        }
        #endregion
        
        #region file saved event
        public delegate void FileSavedEventHandler();
        public event FileSavedEventHandler FileSaved;
        private void FireFileSavedEvent()
        {
            if (FileSaved != null)
            {
                this.FileSaved();
            }
        }
        #endregion
                
        #region water volume changed
        public delegate void WaterVolumeChangedHandler(double value);
        public event WaterVolumeChangedHandler WaterVolumeChanged;
        private void FireWaterVolumeChangedEvent()
        {
            if (WaterVolumeChanged != null)
            {
            	// Calculate shower length
        		double showerLength = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - timestamp;
        		
        		// Calculate water used
        		double waterUsed = calculateAverageRate() * (showerLength/1000);
                this.WaterVolumeChanged(waterUsed);
            }
        }
        #endregion
    }
}
