package de.nanoleaf.server;

import java.io.IOException;
import java.util.List;

import io.github.rowak.nanoleafapi.Color;
import io.github.rowak.nanoleafapi.NanoleafDevice;
import io.github.rowak.nanoleafapi.NanoleafException;
import io.github.rowak.nanoleafapi.Panel;
import io.github.rowak.nanoleafapi.event.DetailedTouchEvent;
import io.github.rowak.nanoleafapi.event.NanoleafTouchEventListener;
import io.github.rowak.nanoleafapi.event.TouchEvent;

public class NanoleafDeviceServer {

	private String m_nanoleafHostname = "Canvas-72FA.fritz.box";
	public String getNanoleafHostname() { return m_nanoleafHostname; }
	
	private String m_nanoleafHostIP = "";
	public String getNanoleafHostIP() {	return m_nanoleafHostIP; }
	
	private int m_nanoleafPort = 16021;
	public int getNanoleafPort() { return m_nanoleafPort; }
	
	private String m_nanoleafApiLevel = "v1";
	public String getNanoleafApiLevel() { return m_nanoleafApiLevel; }
	
	private String m_nanoleafAccessToken = "LAG28BQWrXK2p79NbHMQsvcYYCN1TcD4";
	public String getNanoleafAccessToken() { return m_nanoleafAccessToken; }

	private NanoleafDevice m_nanoleafDevice = null;
	public NanoleafDevice getNanoleafDevice() { return m_nanoleafDevice; }
	
	private int m_nanoleafTouchTimer = 50;
	public int getNanoleafTouchTimer() { return m_nanoleafTouchTimer; }
	public void setNanoleafTouchTimer(int nanoleafTouchTimer) { m_nanoleafTouchTimer = nanoleafTouchTimer; }
	
	private Integer m_nanoleafLastID = null;
	public Integer getNanoleafLastID() { return m_nanoleafLastID; }
	public void setNanoleafLastID(Integer nanoleafLastID) { m_nanoleafLastID = nanoleafLastID; }
	
	private List<Panel> m_nanoLeafPanels = null;
	public List<Panel> getNanoLeafPanels() { return m_nanoLeafPanels; }
	
	
	public NanoleafDeviceServer() {
		
	}
	
	public NanoleafDeviceServer(String nanoleafHostname, String nanoleafHostIP, int nanoleafPort, String nanoleafAccessToken) {
		this.m_nanoleafHostname = nanoleafHostname;
		this.m_nanoleafHostIP = nanoleafHostIP;
		this.m_nanoleafPort = nanoleafPort;
		this.m_nanoleafAccessToken = nanoleafAccessToken;
	}
	
	public boolean deConnectNanoLeaf() throws NanoleafException, IOException {
		boolean finish = false;
		try {
			getNanoleafDevice().closeEventListeners();
			getNanoleafDevice().closeTouchEventListeners();
			getNanoleafDevice().closeAsync();
			m_nanoleafDevice = null;
			getNanoLeafPanels().clear();
			
			finish = true;
		} catch (Exception e) {
			throw e;
		}
		
		
		return finish;
	}
	
	public boolean connectNanoLeaf() throws NanoleafException, IOException {
		boolean connected = false;
		
		try {
			m_nanoleafDevice = NanoleafDevice.createDevice(getNanoleafHostname(), getNanoleafPort(), getNanoleafAccessToken());
			
			if (m_nanoleafDevice != null) {
				connected = true;
				refreshPanels();
			}
		} catch (Exception e) {
			throw e;
		}
		return connected;
	}
	
	private void refreshPanels() throws NanoleafException, IOException {
		
		if (getNanoleafDevice() != null) {
			m_nanoLeafPanels = getNanoleafDevice().getPanels();
		}
	}
	
	private boolean checkLastIdActiv(Integer lastID) {
		
		if (getNanoleafLastID() == null) {
			return false;
		}
		
		return getNanoleafLastID().equals(lastID);
	}

	public void startNanoLeafEvent() {
		
		
		
		try {
			getNanoleafDevice().setColor(Color.BLACK);
			
			getNanoleafDevice().enableExternalStreaming();    
			
			getNanoleafDevice().enableTouchEventStreaming(getNanoleafPort()); // You need to specify a port to listen on
			getNanoleafDevice().registerTouchEventStreamingListener(new NanoleafTouchEventListener() {
	            @Override
	            public void onOpen() {
	                // Called when the listener is created
	            }

	            @Override
	            public void onClosed() {
	                // Called when the listener is closed
	            }

	            @Override
	            public void onEvent(DetailedTouchEvent[] events) {
	                // Called when a touch event occurs
	            	//System.out.println("Events: " + events.length);
	            	
	            	DetailedTouchEvent event = events[0];
	            	
	            	Integer lastID = event.getPanelId();
	            	
	            	
	            	
	            	
	            	//TouchEvent touch = event.getTouchType();
	            	
	            	switch (event.getTouchType()) {
					case TouchEvent.DOUBLE_TAP: 
						//System.out.println("DOUBLE_TAP");				
						break;
						
					case TouchEvent.SINGLE_TAP:
						//System.out.println("SINGLE_TAP");
						if (checkLastIdActiv(lastID)) {
		            		return;
		            	} else {
		            		setNanoleafLastID(lastID);
		            		
		            		try {
		            			
		            			getNanoleafDevice().setPanelExternalStreaming(lastID, Color.RED, 1);

		            			
		            		} catch (Exception e) {
								e.printStackTrace();
							}
		            		
		            		
		            		
		            		System.out.println("ID: " + event.getPanelId());
		            	}
						
						
						break;
						
					case TouchEvent.HOLD:
						//System.out.println("HOLD");
						break;
						
					case TouchEvent.UNKNOWN_ATTRIBUTE:
						//System.out.println("UNKNOWN_ATTRIBUTE");
						break;
						
						
					default:
						System.out.println("Unexpected value: " + event.getTouchType());
					} 
	            }
				
	        });
		} catch (Exception e) {
			e.printStackTrace();
		}
		
        
	}

	public static void main(String[] args) {
		NanoleafDeviceServer nanoleafDeviceServer = new NanoleafDeviceServer();
		try {
			boolean nanoLeafActiv = nanoleafDeviceServer.connectNanoLeaf();
			
			if (nanoLeafActiv) {
				nanoleafDeviceServer.startNanoLeafEvent();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		

	}

}
