package com.grt192.controller.hauntedhouse;
import com.grt192.core.Mechanism;
import com.grt192.core.StepController;
import com.grt192.mechanism.hauntedhouse.HauntedHouseMechanism;
import com.grt192.event.component.SwitchListener;
import com.grt192.mechanism.hauntedhouse.HHLEDMechanism;
import com.grt192.sensor.GRTSwitch;
import java.util.Random;
/**
* Actuates mechanisms automatically or manually. If MasterAutoSwitch is on
* manual operation, moving switch will toggle actuator cylinder position.
* If auto, moving switch will toggle auto operation. This also has
* Network Control
* @author data, ajc, nik.lele
*/
public class HauntedHouseController extends StepController implements SwitchListener {
//sleep commands
public static final boolean EXTEND = true;
public static final boolean RETRACT = false;
//delays arrays indicies
private static final int MIN_OPEN = 0;
private static final int MAX_OPEN = 1;
private static final int MIN_CLOSED = 2;
private static final int MAX_CLOSED = 3;
//button states
private boolean master;
private boolean auto;
private boolean enabled;
//mechanism
private HauntedHouseMechanism hhm;
private String mechID;
//switches
private static GRTSwitch masterSwitch;
private static GRTSwitch autoSwitch;
private GRTSwitch mySwitch;
private String switchID;
//delays
private int[] delays;
private boolean randomDelay;
private static Random r;
public HauntedHouseController(int solPin, int switchPin, int[] delays) {
initMechanism(solPin, switchPin);
initSwitches(solPin, switchPin);
initDelays(delays);
}
public void initDelays(int[] delays) {
//set delays for auto function
this.delays = delays;
if(r == null) {
r = new Random();
}
}
public void initMechanism(int solPin, int switchPin) {
//construct mechanism
hhm = new HauntedHouseMechanism(solPin, switchPin);
mechID = "HH" + solPin;
System.out.println("Constructing " + mechID);
addMechanism(mechID, hhm);
}
//TODO decide to implement or remove
//not good for abstraction, but will surely work
//call this from HHLEDController to add all switches to all of these
//master and auto must be static
public static void initMasterAutoSwitch() {
}
/**
* Precondition: initMechanism() called
* @param solPin
* @param switchPin
*/
public void initSwitches(int solPin, int switchPin) {
//local switch
switchID = "Switch" + switchPin;
//listen for manual or auto commands
mySwitch = (GRTSwitch) hhm.getSensor(switchID);
mySwitch.addSwitchListener(this);
//TODO fix instantiation of switches in this control
if (masterSwitch == null) {
masterSwitch = new GRTSwitch(9, 50, "MasterButton");
autoSwitch = new GRTSwitch(10, 50, "AutoButton");
masterSwitch.start();
autoSwitch.start();
}
//TEST THE HASHTABLE--GETTING THE SWITCH FROM AN ALIEN MECH
// Mechanism om = getMechanism(HHLEDController.MECHANISM_ID);
// masterSwitch = (GRTSwitch) om.getSensor(HHLEDMechanism.MASTER_BUTTON_ID);
// autoSwitch = (GRTSwitch) om.getSensor(HHLEDMechanism.AUTO_BUTTON_ID);
//listen
masterSwitch.addSwitchListener(this);
autoSwitch.addSwitchListener(this);
//set starting states of auto and master function
master = HHLEDController.MASTER_DEFAULT_STATE;
auto = HHLEDController.AUTO_DEFAULT_STATE;
}
public void act() {
running = true;
while (running) {
doSleep(EXTEND);
//autonomous loop
if (enabled && master && auto) {
// System.out.println("HauntedHouseController auto extend from " +mechID );
//extend and wait
hhm.extend();
doSleep(RETRACT);
if (master && auto) {
// System.out.println("HauntedHouseController auto retract from " + mechID );
hhm.retract();
}
}
}
}
public void switchPressed(GRTSwitch source) {
System.out.println("HauntedHouseController switch press from " + mechID);
if (source == mySwitch) {
enabled = true;
if (!auto && master) {
hhm.extend();
}
}
}
public void switchReleased(GRTSwitch source) {
System.out.println("HauntedHouseController switch release from " + mechID);
if (source == mySwitch) {
enabled = false;
if (!auto && master) {
hhm.retract();
}
}
if (source == masterSwitch) {
master = !master;
System.out.println("Master switch to " + master + "from " + mechID);
}
if (source == autoSwitch) {
auto = !auto;
System.out.println("Auto switch to " + auto + "from " + mechID);
}
}
/**
* Keep the Mechanism at a given state for a calculated amount of time
* @param open flag for which type of delay is used-- open true for open
*/
public void doSleep(boolean open) {
try {
Thread.sleep(getSleepTime(open));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
/**
* Get the sleep time for a given state. This defaults to minimum if
* !randomDelay
* @param open flag for which type of delay used-- open true for open
* @return time in ms for sleep
*/
public long getSleepTime(boolean open) {
int low = open ? delays[MIN_OPEN] : delays[MIN_CLOSED];
int high = open ? delays[MAX_OPEN] : delays[MAX_CLOSED];
//we indicate !randomness by a negative high value
if (high < 0) {
// System.out.println("HHControl "+ mechID + "is not random");
//low is default
return low;
}
//fast! calculation of time
return (long) ((high - low) * r.nextDouble() + low);
}
public void setMaster(boolean b) {
master = b;
}
public void setEnabled(boolean b) {
enabled = b;
if (!auto && master) {
if (enabled) {
hhm.extend();
} else {
hhm.retract();
}
}
}
public void setAuto(boolean b) {
if (!auto && master) {
if (enabled) {
hhm.extend();
} else {
hhm.retract();
}
}
}
public boolean getEnabled() {
return enabled;
}
public boolean getMaster() {
return master;
}
public boolean getAuto() {
return auto;
}
}