package auto;

import java.io.*;
import java.net.*;

public class Sender {
	DatagramSocket socket = null;
	InetAddress receiverAddress = null;
	int sendPort = 6787;
	int interPacketsInterval = 0;
	long packetCounter = 0;

	SenderMonitor monitor = null;
	
	long last = System.currentTimeMillis();
	long current = 0;

	int lastStatus = -1;
	int status = 0;
	long lastStatusTimestamp = System.currentTimeMillis();
	
	public Sender(InetAddress receiverAddress, int interPacketsInterval) {
		this.receiverAddress = receiverAddress;
		this.interPacketsInterval = interPacketsInterval;
		try {
			socket = new DatagramSocket(sendPort);
		} catch (SocketException e) {
			e.printStackTrace();
		}

		monitor = new SenderMonitor();
		monitor.start();
	}

	private String setHeader(int i, int size, int delay) {
		//index
		String ret = i + ";";
		//timestamp
		ret += System.currentTimeMillis() + ";";
		//size
		ret += size + ";";
		//delay
		ret += delay + ";";
		return ret;
	}

	private DatagramPacket getPacket(int counter, int size, int delay) {
		byte[] buffer = new byte[size];
		String label = setHeader(counter, size, delay);
		for (int i = 0; i < label.length() && i < size; i++)
			buffer[i] = label.getBytes()[i];
		DatagramPacket packet =
			new DatagramPacket(buffer, size, receiverAddress, sendPort);
		return packet;
	}

	public void run() throws InterruptedException {
		while (true) {
			try {
				int status = monitor.getStatus();

				verifyStatusChanging(status);

				if (status == 0) {
					do {
						current = System.currentTimeMillis();
					} while ((last + interPacketsInterval) > current);
					DatagramPacket packet = getPacket((int) packetCounter++, 2000, interPacketsInterval); 
					socket.send(packet);
				} 
				else if (status == 1) {
					do {
						current = System.currentTimeMillis();
					} while ((last + (interPacketsInterval / 2)) > current);
					DatagramPacket packet = getPacket((int) packetCounter++, 1000, interPacketsInterval/2); 
					socket.send(packet);
				} else if (status == 2) {
					do {
						current = System.currentTimeMillis();
					} while ((last + interPacketsInterval) > current);
					DatagramPacket packet = getPacket((int) packetCounter++, 1000, interPacketsInterval); 
					socket.send(packet);
				} else if (status == 3) {
					Thread.sleep(300);
				}
				last = current;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void verifyStatusChanging(int status) {
		//Process status changing
		if (lastStatus != status) {
			long changeTime = System.currentTimeMillis();
			//Deixou de enviar
			float economia = changeTime - lastStatusTimestamp;
			economia /= 1000;
			if (lastStatus == 2) {
				System.out.println("Deixei de mandar: " + economia);
			} else if (lastStatus == 3) {
				System.out.println("Deixei de mandar: " + economia * 2);
			}
			//					System.out.println(System.currentTimeMillis() + " " + status);
			System.out.println("Changed from " + lastStatus + " to " + status );
			lastStatus = status;
			lastStatusTimestamp = changeTime;
		}
	}

	public static void main(String argv[]) throws Exception {
		if (argv.length == 0) {
			System.out.println(
				"Usage: java auto.Sender receiverAddress interPacketsInterval");
			System.exit(0);
		}

		InetAddress receiverAddress = InetAddress.getByName(argv[0]);
		int interPacketsInterval = (new Integer(argv[1])).intValue();

		Sender senderInstance =
			new Sender(receiverAddress, interPacketsInterval);
		senderInstance.run();
	}

}
