/*
* This file is part of the Remote Sensor Actuator Interface (ReSAI).
*
* Copyright(c) Andreas Kipp, Frederic Siepmann
* http://opensource.cit-ec.de/projects/resai
*
* This file may be licensed under the terms of of the
* GNU Lesser General Public License Version 3 (the ``LGPL''),
* or (at your option) any later version.
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the LGPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the LGPL along with this
* program. If not, go to http://www.gnu.org/licenses/lgpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The development of this software was supported by the
* Excellence Cluster EXC 277 Cognitive Interaction Technology.
* The Excellence Cluster EXC 277 is a grant of the Deutsche
* Forschungsgemeinschaft (DFG) in the context of the German
* Excellence Initiative.
*
*/

/**
 * Panel for the evaluation view.
 *
 * @author akipp
 */

package de.unibi.airobots.resaijavaclient.gui.panels.components;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Observable;

import javax.swing.JLabel;

import de.unibi.airobots.resaijavaclient.communicaton.Communicator;
import de.unibi.airobots.resaijavaclient.gui.panels.components.template.PanelTemplate;
import de.unibi.airobots.resaijavaclient.helper.TimeConverter;

public class EvaPanel extends PanelTemplate {

	private static final long serialVersionUID = 1L;
	private JLabel lblServerTime = new JLabel();
	private JLabel lblClientTime = new JLabel();
	private JLabel lblDiff = new JLabel();
	private JLabel lblSendTime = new JLabel();
	private JLabel lblReceiveTime = new JLabel();
	private JLabel lblWorkTime = new JLabel();
	private JLabel lblMessageNo = new JLabel();
	private JLabel lblWorkText = new JLabel();

	private long servertime = 0;
	private long clientTime = 0;
	private long timeDiff = 0;

	private long sendTime = 0;
	private long receiveTime = 0;
	private long workTime = 0;
	private long receiveLatency = 0;
	private long workLatency = 0;
	private int charsCounted = 0;
	private String filename;

	//private CpuMonitor m = new CpuMonitor();

	public EvaPanel() {

		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		add(lblServerTime, c);

		c.gridx = 0;
		c.gridy = 1;
		add(lblClientTime, c);

		c.gridx = 0;
		c.gridy = 2;
		add(lblDiff, c);

		c.gridx = 0;
		c.gridy = 3;
		add(lblSendTime, c);

		c.gridx = 0;
		c.gridy = 4;
		add(lblReceiveTime, c);

		c.gridx = 0;
		c.gridy = 5;
		add(lblWorkTime, c);

		c.gridx = 0;
		c.gridy = 6;
		add(lblMessageNo, c);

	}

	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof Communicator) {
			Communicator com = (Communicator) o;

			HashMap<String, String> recProps = com.getReceivedProperties();

			try {

				if (recProps.containsKey(component + "_HANDSHAKE")) {
					servertime = Long.parseLong(recProps.get(
							component + "_HANDSHAKE").toString());

					clientTime = System.currentTimeMillis();

					lblServerTime.setText(TimeConverter.toDateTime(servertime));
					lblClientTime.setText(TimeConverter.toDateTime(clientTime));

					timeDiff = Math.abs(clientTime - servertime);
					lblDiff.setText(String.valueOf(timeDiff));

					// CREATE DATA FILE
					filename = recProps.get(component + "_FILENAME");
					createLogHead();
				}

				if (recProps.containsKey(component + "_TIME")) {
					receiveTime = System.currentTimeMillis();
					sendTime = Long.parseLong(recProps.get(component + "_TIME")
							.toString());

					receiveLatency = Math.abs(Math.abs(sendTime - receiveTime)
							- timeDiff);
					lblSendTime.setText(TimeConverter.toDateTime(sendTime));
					lblReceiveTime.setText(TimeConverter
							.toDateTime(receiveTime)
							+ "("
							+ receiveLatency
							+ ")");

					lblMessageNo.setText(recProps.get(component + "_MSGNO")
							.toString());

					charsCounted = doWork(recProps);

					workTime = System.currentTimeMillis();
					workLatency = Math.abs(Math.abs(workTime - sendTime)
							- timeDiff);
					lblWorkTime.setText(TimeConverter.toDateTime(workTime)
							+ "(" + workLatency + ")");

					writeLogLine();
					lblWorkText.setText("Chars worked: " + charsCounted);
				}
			} catch (NullPointerException e) {
				e.printStackTrace();
			}
		}
	}

	private void createLogHead() {

		String text = "timeDiff;charsCounted;sendTime;receiveTime;receiveLat;workTime;worklat;\n";

		String clientPath = "logs/";

		try {

			File f = new File(clientPath);
			f.mkdir();

			String clientFile = filename;

			FileWriter fstream;

			File file = new File(clientPath + "/" + clientFile);
			if(file.exists()) {
				file.delete();
			}
			
			fstream = new FileWriter(clientPath + "/" + clientFile, true);

			BufferedWriter out = new BufferedWriter(fstream);
			out.write(text);

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void writeLogLine() {

		String clientPath = "logs/";

		try {

			String clientFile = filename;

			FileWriter fstream;

			fstream = new FileWriter(clientPath + "/" + clientFile, true);

			String text = timeDiff + ";" + charsCounted + ";" + sendTime + ";"
					+ receiveTime + ";" + receiveLatency + ";" + workTime + ";"
					+ workLatency + ";\n";// + m.getCpu() + ";\n";

			BufferedWriter out = new BufferedWriter(fstream);
			out.write(text);

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method iterates over all properties and adds their value length to
	 * the return value.
	 * 
	 * @param receivedProperties
	 */
	private int doWork(HashMap<String, String> receivedProperties) {
		int characters = 0;
		for (String prop : receivedProperties.keySet()) {
			for (int i = 0; i < receivedProperties.get(prop).length(); i++) {
				characters++;
			}
		}
		return characters;
	}

}