package com.grt192.mechanism.cannonbot;
import com.grt192.actuator.GRTSolenoid;
import com.grt192.actuator.GRTTwoWaySolenoid;
import com.grt192.core.Mechanism;
import com.grt192.event.component.SwitchListener;
import com.grt192.mechanism.GRTCompressor;
import com.grt192.sensor.GRTSwitch;
/**
* Dual barrel cannon assembly, with a system for pressurizing one barrel while
* the other is firing
*/
public class CBCannon extends Mechanism implements SwitchListener {
// Constants
public static final int SLEEP_TIME = 50;
public static final int LEFT_BARREL = 0;
public static final int RIGHT_BARREL = 1;
public static final long TIMEOUT_LENGTH = 2000;
// Parts
private GRTTwoWaySolenoid tankSelectorSolenoid;
private GRTSolenoid tankASolenoid;
private GRTSolenoid tankBSolenoid;
private GRTCompressor cannonCompressor;
private GRTSwitch fireSwitch;
// Properties
private boolean firing;
private boolean leftReady = false;
private boolean rightReady = false;
private int activeBarrel;
private int inactiveBarrel;
public CBCannon(int tasolpin, int tbsolpin, int tssolpin1, int tssolpin2,
GRTCompressor compressor) {
this(new GRTSolenoid(tasolpin), new GRTSolenoid(tbsolpin),
new GRTTwoWaySolenoid(tssolpin1, tssolpin2),
compressor);
}
public CBCannon(GRTSolenoid tankasol, GRTSolenoid tankbsol,
GRTTwoWaySolenoid tankselecsol, GRTCompressor compressor) {
this.leftReady = false;
this.rightReady = false;
this.activeBarrel = LEFT_BARREL;
this.inactiveBarrel = RIGHT_BARREL;
this.tankASolenoid = tankasol;
tankASolenoid.start();
this.tankBSolenoid = tankbsol;
tankBSolenoid.start();
this.tankSelectorSolenoid = tankselecsol;
tankSelectorSolenoid.start();
this.fireSwitch = new GRTSwitch(3, 9, "fireswitch");
fireSwitch.start();
this.cannonCompressor = compressor;
if(!compressor.isStarted())
cannonCompressor.startCompressor();
addActuator("tankasol", tankASolenoid);
addActuator("tankbsol", tankBSolenoid);
addActuator("tankselecsol", tankSelectorSolenoid);
addSensor("fireswitch", fireSwitch);
// listen to the projectile switch
fireSwitch.addSwitchListener(this);
// register this as a switch listener for the compressor
((GRTSwitch) cannonCompressor.getSensor("pressureSwitch"))
.addSwitchListener(this);
}
// Actions
/**
* if barrel ready Opens and closes solenoid timed by delay and sensor
* (which ever comes first)
*/
public void fire() {
// make sure we're ready to fire.
// just in case we have a full tank and dont notice
if ((activeBarrel == LEFT_BARREL && !leftReady)
|| (activeBarrel == RIGHT_BARREL && !rightReady)) {
if (leftReady) {
switchActiveBarrel();
fire();
} else if (rightReady) {
switchActiveBarrel();
fire();
}
return;
}
// open the valve
getActuator((activeBarrel == LEFT_BARREL) ? "tankasol" : "tankbsol")
.enqueueCommand(GRTSolenoid.ON);
firing = true;
// flag the barrel just fired as not ready;
// timeout:
long startTime = System.currentTimeMillis();
while (firing
&& System.currentTimeMillis() - startTime < TIMEOUT_LENGTH) {
// block
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
// close the valve
getActuator((activeBarrel == LEFT_BARREL) ? "tankasol" : "tankbsol")
.enqueueCommand(GRTSolenoid.OFF);
if (activeBarrel == LEFT_BARREL) {
leftReady = false;
if (rightReady) {
switchActiveBarrel();
}
} else if (activeBarrel == RIGHT_BARREL) {
rightReady = false;
if (leftReady) {
switchActiveBarrel();
}
}
}
public void switchPressed(GRTSwitch source) { // Compressors are ready
// which tank were we changing when we left off?
// Which tank was INACTIVE?
// that one is now FULL.
if (source.getId().equals("pressureSwitch")) {
if (inactiveBarrel == LEFT_BARREL) {
leftReady = true;
switchActiveBarrel();
// put the two way valve in the right place
} else if (inactiveBarrel == RIGHT_BARREL) {
rightReady = true;
switchActiveBarrel();
// put the two way valve in the right place
}
} else if (source.getId().equals("fireSwitch")) {
firing = false;
}
}
// Overrides
public void fireLeft() {
this.tankASolenoid.enqueueCommand(GRTSolenoid.ON);
}
public void fireRight() {
this.tankBSolenoid.enqueueCommand(GRTSolenoid.ON);
}
public void closeLeft() {
this.tankASolenoid.enqueueCommand(GRTSolenoid.OFF);
}
public void closeRight() {
this.tankASolenoid.enqueueCommand(GRTSolenoid.OFF);
}
public void switchActiveBarrel() {
activeBarrel = (activeBarrel == LEFT_BARREL ? RIGHT_BARREL
: LEFT_BARREL);
inactiveBarrel = (activeBarrel == LEFT_BARREL ? RIGHT_BARREL
: LEFT_BARREL);
if (inactiveBarrel == RIGHT_BARREL) {
tankSelectorSolenoid.enqueueCommand(GRTTwoWaySolenoid.FORWARD);
} else if (inactiveBarrel == LEFT_BARREL) {
tankSelectorSolenoid.enqueueCommand(GRTTwoWaySolenoid.REVERSE);
}
}
public void switchReleased(GRTSwitch source) {
}
public boolean isFiring() {
return firing;
}
public boolean isLeftReady() {
return leftReady;
}
public boolean isRightReady() {
return rightReady;
}
public int getActiveBarrel() {
return activeBarrel;
}
public int getInactiveBarrel() {
return inactiveBarrel;
}
public boolean readyToFire() {
return leftReady || rightReady;
}
}