package devices;

import anywheresoftware.b4a.BA;
import jGPIO.jGPIO;
import jGPIO.DigitalOutput.DigitalOutput;
import jGPIO.DigitalOutput.DigitalOutputEvent;

@BA.ShortName("HardwareRelay")

/**
 * Relay Class
 * use DigitalOutput class
 * @author rdkartono
 *
 */
public class Relay implements DigitalOutputEvent {
	private DigitalOutput dox;
	private int mypinnumber;
	private BA ba;
	private boolean initialized = false;
	private boolean isON = false;
	private boolean activelow = false;
	
	/**
	 * Initialize relay Object
	 * @param pin_number : pin number connected to relay
	 * @param activelow : if true, logic low will turn ON relay, logic high will turn OFF relay
	 * @return true if Initialize success
	 */
	public boolean Initialize(BA bax, int pin_number, boolean activelow) {
		this.mypinnumber = pin_number;
		this.ba = bax;
		this.activelow = activelow;
		initialized = false;
		if (jGPIO.osname=="") jGPIO.detectOS();
		
		if (jGPIO.IsLinux==false) {
			return false;
		}
		
		dox = new DigitalOutput();
		dox.SetJavaEvent(this);
		dox.Initialize(this.ba, null, "digitalout", mypinnumber, false);
		initialized = dox.getIsInitialized();
		if (initialized) {
			Turn_OFF();		// turn off relay
		}
		
		
		 Runtime.getRuntime().addShutdownHook(new Thread() {
	            @Override
	            public void run() {
	                Close();
	            }
	        });
		 
		return initialized;
	}
	
	public void Close() {
		if (dox instanceof DigitalOutput) {
			dox.Release();
			dox = null;
		}
		
		initialized = false;
	}
	
	/**
	 * Check if Initialzied
	 * @return true if already initialized
	 */
	public boolean getIsInitialized() {
		return initialized;
	}
	
	/**
	 * Turn ON relay
	 * @return true if success
	 */
	public boolean Turn_ON() {
		if (initialized) {
			boolean result = false;
			if (activelow) {
				result= dox.SetLow();
			} else {
				result= dox.SetHigh();
			}
			if (result) isON = true;
			return result;
			
		}
		return false;
	}
	
	/**
	 * Turn OFF relay
	 * @return true if success
	 */
	public boolean Turn_OFF() {
		if (initialized) {
			boolean result = false;
			if (activelow) {
				result= dox.SetHigh();
			} else {
				result= dox.SetLow();
			}
			if (result) isON = false;
			return result;
		}
		return false;
	}
	
	/**
	 * Get Current relay status;
	 * @return true if Relay ON
	 */
	public boolean Relay_is_ON() {
		return isON;
	}

	@Override
	@BA.Hide
	public void error(int pinnumber, String Msg) {
		BA.Log("Relay error, pin="+pinnumber+", Msg = "+Msg);
	}

	@Override
	@BA.Hide
	public void newoutstate(int pinnumber, boolean isOn) {
		if (BA.debugMode) {
			BA.Log("Relay New Out State, pin="+pinnumber+" Value = "+isOn);
		}
		
	}
}
