package code;
import java.util.HashMap;
import java.util.Map;

import anywheresoftware.b4a.BA;


@BA.Version(0.06f)
@BA.ShortName("jVAPIX")
@BA.Events(values= {
		"log(msg as string)"
})
public class JVAPIX {
	private BA ba = null;
	private String event = null;
	private Object Me = this;
	//private ExecutorService exec = Executors.newCachedThreadPool();
	
	private boolean inited = false;
	private boolean need_log_event = false;
	private Map<String, VapixDevice> devices = new HashMap<String,VapixDevice>();
	
	
	/**
	 * Initialize jAxisAudio
	 * @param event eventname
	 */
	public void Initialize(BA ba, String event) {
		this.ba = ba;
		this.event = event;
		if (this.ba!=null) {
			if (this.event!=null) {
				if (this.event.length()>0) {
					inited = true;
					need_log_event = this.ba.subExists(event+"_log");
				}
			}
		}
	}
	
	/**
	 * Connect to a Vapix Device
	 * Connected VapixDevice is stored in a Map
	 * @param hostname hostname or IP 
	 * @param port port number
	 * @param username username
	 * @param password password
	 * @return true if can be connected and a valid Vapix Device
	 */
	public boolean Connect(String hostname, int port, String username, String password, String localip) {
		VapixDevice dev = new VapixDevice(hostname, port, username, password, localip);
		
		boolean success = dev.GetParametersFromDevice();
		if (!success) success = dev.GetParametersFromDevice();		// ambil kedua kali 
		
		if (success) {
			
			if (dev.getHTTPVersion().equals("3") && dev.IsAudioDevice()) {
				raise_log("Device at "+hostname+":"+port+" is VapixAudio");
				VapixAudio va = new VapixAudio(dev);
				VapixDevice prev = devices.put(hostname, va);
				if (prev!=null) {
					raise_log("Connect to "+hostname+":"+port+" has replaced a VapixDevice with SerialNumber="+prev.getSerialNumber()+", MAC="+prev.getMACAddress());
				}
			}
			
			return true;
		}
		return success;		//kalau gagal , berarti bukan Vapix Device
	}
	
	/**
	 * Get all Connected Vapix Devices
	 * @return array of IP Address
	 */
	public String[] ConnectedDevices() {
		if (devices.size()>0) {
			return devices.keySet().stream().toArray(String[]::new);
		} else return new String[0];
	}
	
	/**
	 * Disconnect a Vapix Device
	 * @param ip IP Address to disconnect
	 * @return true if can be disconnect
	 */
	public boolean DisconnectDevice(String ip) {
		if (devices.size()>0) {
			VapixDevice dev = devices.get(ip);
			if (dev!=null) {
				dev.Close();
				devices.remove(ip);
				dev = null;
			}
		}
		return false;
	}
	
	/**
	 * Get Connected Vapix Device with specific ip address
	 * Object returned must be check if instanceof valid type, such as VapixAudio
	 * @param ipaddress ip address to search
	 * @return null if not exists
	 */
	public Object GetConnectedDevice(String ipaddress) {
		return devices.get(ipaddress);
	}
	
	/**
	 * Check if this Object is initialized
	 * @return true if inited
	 */
	public boolean IsInitialized() {
		return inited;
	}
	
	private void raise_log(String msg) {
		if (ba!=null) {
			if (need_log_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_log", false, new Object[] {msg});	
		} else System.out.println(msg);
		
	}
}
