/* GMM (C) 2018 Stephane Charette <stephanecharette@gmail.com>
 * $Id: TabCanvas.hpp 2640 2018-10-18 08:35:21Z stephane $
 */

#pragma once

#include "GMM.hpp"


/** The number of "buckets" needed to show the moisture levels.  Normally will be 17, used to define buckets for 8%
 * through to 24%.  This is used at compile time to allocate a number of text fields and labels shown at the bottom
 * of each tab.
 */
#define number_of_buckets 17

/** Only a small number of buckets are created, the first of which is 8%, and incrementing by 1 until all buckets
 * have been assigned.  Normally goes from 8% to 24%.
 */
#define percentage_of_first_bucket 8

class TabCanvas : public Component, public Timer, public Thread
{
	public:

		TabCanvas(const std::string & name);

		virtual ~TabCanvas(void);

		virtual void resized(void);

		/// Inherited from Timer.  Used to redraw the chart.
		virtual void timerCallback(void);

		virtual void periodic_update(void);

		virtual void calculate_averages_and_std_deviations(void);

		virtual Image draw_chart(const size_t width, const size_t height);

		/// Inherited from Thread.  Used to handle the serial device.
		virtual void run(void);

		/// Secondary thread which is started to handle the serial device.
		virtual void device_thread(void);

		virtual void write_mc_file(void);

		virtual void open_serial_device(const std::string & device_name);

		virtual void close_serial_device(void);

		virtual std::string read_from_device(VBytes & read_buffer);

		virtual std::string get_simulated_string(VBytes & read_buffer);

		const std::string prefix;

		/** Used to determine if this tab is the currently-selected tab in the notebook.  Is updated by the Notebook
		 * object whenever a new tab gets focus.  @see @ref Notebook::currentTabChanged()
		 */
		bool		tab_is_active;

		bool		export_image;

		/// Determines how often the timer should trigger.  This is used to redraw the chart and update the screen.
		int			timer_frequency_in_milliseconds;

		HANDLE		comm_handle;

		/// Count the number of boards in each bucket.
		size_t run_moisture_bucket[number_of_buckets];	///< These values are shown in @ref total_distribution[]
		size_t pkg_moisture_bucket[number_of_buckets];	///< These values are shown in @ref local_distribution[]

		LDouble		run_doubles;
		LDouble		pkg_doubles;

		/// The sum of moisture levels for all packages within the current run.  This is updated at every board, and used to find the average and standard deviation.
		double		run_sum;

		/// Similar to @ref run_sum but for the current package.
		double		pkg_sum;

		/// The average moisture content for all packages within the current run.  This is updated at every board.
		double		run_average;

		/// Similar to @ref run_average but for the current package.
		double		pkg_average;

		double		run_std_dev;
		double		pkg_std_dev;

		Label		kiln_num_label;
		TextEditor	kiln_num_editor;

		Label		run_label;
		TextEditor	run_editor;

		Label		pkg_label;
		TextEditor	pkg_editor;

		Label		total_number_of_boards_label;				///< "Boards:"
		TextEditor	total_number_of_boards_editor;
		Label		total_average_moisture_label;				///< "Average:"
		TextEditor	total_average_moisture_editor;
		Label		total_std_dev_moisture_label;				///< "Std. dev:"
		TextEditor	total_std_dev_moisture_editor;

		Label		local_number_of_boards_label;				///< "Boards:"
		TextEditor	local_number_of_boards_editor;
		Label		local_average_moisture_label;				///< "Average:"
		TextEditor	local_average_moisture_editor;
		Label		local_std_dev_moisture_label;				///< "Std. dev:"
		TextEditor	local_std_dev_moisture_editor;

		Label		run_header;									///< "Run:"
		Label		pkg_header;									///< "Pkg:"

		TextEditor	total_distribution	[number_of_buckets];	///< These text fields are populated using the numbers in @ref total_moisture_content[].
		Label		percentages			[number_of_buckets];	///< 8%, 9%, 10%, 11%, ...
		TextEditor	local_distribution	[number_of_buckets];	///< These text fields are populated using the numbers in @ref local_moisture_content[].

		ImageComponent chart;

		VStr		warnings_and_errors;
};
