#charset "us-ascii"
#include <advlite.h>

//      The Junction Box and its classes.

// B6 for the top and 9D for the bottom:
// 1011 0110
// 1001 1101

// A new preCond -- we're going to try tinkering with objHeld.
// Not sure why this was needed.

modify Thing
    isConnected = nil
;

objHeldUnless: objHeld
    checkPreCondition(obj, allowImplicit)
    {
        if (obj.isConnected) return true;
        else return inherited(obj, allowImplicit);
    }
;

powerCable: PDportable 'thick cable; power' @lampStoreWorkTable
    "The cable is only about 30cm long. It has a square multipin connector at
    one end and a round multipin connector at the other end. <<describeAttached>>"
    bulk = 15
    describeAttached() {
        if (squareAttached && roundAttached)
            "Both ends of the cable are plugged into the panel. ";
        else if (squareAttached || roundAttached)
            "One end of the cable is securely plugged into the panel. ";
        else return;
    }
    dobjFor(PlugInto) {
        verify() {}
        check() {
            "That\'s a bit vague. You might try plugging the square connector
            or the round connector into something. ";
        }
    }
    // The player might try to put the power cable into the shopping bag, for instance,
    // or the purse, even if one or both ends is attached to the panel:
    dobjFor(PutIn) {
        preCond = [objVisible]
        verify() {}
        check() {
            if (gIobj && (gIobj != connectorPanel) && (gIobj != squareJack) && (gIobj != roundJack)) {
                if (squareAttached || roundAttached) "The cable is attached to the panel. ";
            }
        }
        action() {
            if (gIobj == squareJack) doInstead (PutIn, squareConnector, squareJack);
            else if (gIobj == roundJack) doInstead (PutIn, roundConnector, roundJack);
            else inherited;
        }
    }
    dobjFor(Pull) {
        verify() {}
        check() {
            if (squareAttached || roundAttached) "You're unable to pull the
                cable free from the panel. ";
        }
        action() {
            doInstead(Take, self);
        }
    }
    dobjFor(AttachTo) {
        verify() { illogical ( tryAttachingMsg ); }
    }
    dobjFor(Attach) {
        verify() { illogical ( tryAttachingMsg ); }
    }
    tryAttachingMsg = 'That\'s a bit vague. If you want to attach the square connector
        or the round connector to something, a more specific command will most likely work better. '
    squareAttached = nil
    roundAttached = nil
    dobjFor(Take) {
        check() {
            inherited;
            if (squareAttached && roundAttached)
                "You're unable to detach the connectors from the jacks. ";
            else if (squareAttached || roundAttached)
                "You're unable to detach the connector from the jack. ";
        }
    }
;
+ squareConnector: Component 'square connector; multipin; pins end' 
    desc() {
        if (isBent) "The pins in the square connector look to be a bit bent. ";
        else if (!powerCable.squareAttached) "The square
            connector looks as if it would fit into a square multipin jack. ";
        else "The square connector is securely plugged into the square jack. ";
    }
    vocabLikelihood = 15
    isBent = true
    dobjFor(Straighten) {
        verify() { logical; }
        check() {
            if (!isBent) "You've already straightened the connector pins. ";
            else if (!screwdriver.isDirectlyIn(me)) {
                if (screwdriver.isIn(me)) "You can't do that with your bare fingernails,
                    but possibly the screwdriver would do the job. ";
                else "You don't seem to have a suitable tool
                with which to do that. ";
            }
        }
        action() {
            isBent = nil;
            connectorAch.awardPointsOnce();
            "Using the screwdriver, you deftly straighten out the bent pins in the square connector. ";
        }
    }
    dobjFor(StraightenWith) {
        verify() { logical; }
        check() {
            if (!isBent) "You've already straightened the connector pins. ";
            else if (gIobj != screwdriver) "{The subj iobj} {is} not the right tool for the job. ";
        }
        action() {
            doInstead (Straighten, self);
        }
    }
    dobjFor(AttachTo) asDobjFor(PutIn)
    dobjFor(PlugInto) asDobjFor(PutIn)
    dobjFor(PutIn) {
        preCond = [touchObj]
        verify() { logical; }
        check() {
            if (gIobj != squareJack) "The connector doesn't fit there. ";
            else if (isBent) "The connector is obviously the right shape, but
                for some reason it's not fitting into the jack. ";
        }
        action() {
            powerCable.moveInto(junctionBox.remapIn);
            powerCable.squareAttached = true;
            junctionBox.powerCheck();
        }
    }
;
+ roundConnector: Component 'round connector; multipin; end'
    "The round connector <<if (powerCable.roundAttached)>>is securely plugged
    into the round <<else>>looks as if it would fit into a round multipin <<end>>jack. "
    dobjFor(PlugInto) asDobjFor(PutIn)
    dobjFor(AttachTo) asDobjFor(PutIn)
    dobjFor(PutIn) {
        preCond = [touchObj]
        verify() { logical; }
        check() {
            if (gIobj != roundJack) "The connector doesn't fit there. "; 
        }
        action() {
            powerCable.moveInto(junctionBox.remapIn);
            powerCable.roundAttached = true;
            junctionBox.powerCheck();
        }
    }
;

class JunctionSwitch: Component, Switch
    vocab = 'switch'
    desc = "It's a two-position switch. At present it's switched <<if isOn>>up<<else>>down<<end>>. "
    letter = 'X'
    collectiveGroups = [pluralSwitches]
    dobjFor (Pull) asDobjFor (SwitchVague)
    dobjFor (Push) asDobjFor (SwitchVague)
    dobjFor (SwitchVague) {
        action() {
            inherited;
            connectorPanel.showSwitches();
            junctionBox.powerCheck();
        }
    }
    dobjFor (SwitchOn) {
        action() {
            inherited;
            connectorPanel.showSwitches();
            junctionBox.powerCheck();
        }
    }
    dobjFor (SwitchOff) {
        action() {
            inherited;
            connectorPanel.showSwitches();
            junctionBox.powerCheck();
        }
    }
;


//-----------------------------------------------------------------
// The box itself
//-----------------------------------------------------------------

junctionBox: Fixture 'gray metal box; junction power square' @footOfPole
    "The square gray metal box is affixed to the rear wall of Stufftown. It's a bit more than
    a foot (40 centimeters) on each side, and has a hinge along one edge<<if isOpen>>. Within the box is a panel with two
    rows of switches and a pair of jacks<<end>>. <<if isPowered>>A low electrical
    hum is emanating from the box. <<end>>"
    hideFromAll(action) {
        if (action == Take) return true;
        else return inherited(action);
    }
    contentsListedInExamine = nil
    isOpen = nil
    isPowered = nil    
    remapOn: SubComponent {
        notifyInsert(obj) {
            "You can\'t put things on the gray metal box. ";
            exit;
        }
    }
    remapIn: SubComponent {
        isOpenable = true
        isOpen = nil
        notifyInsert(obj) {
            "There's no room for anything in the box. ";
            exit;
        }
        dobjFor(Open) {
            action() {
                gPlayerChar.setHasSeen(connectorPanel);
                inherited();
            }
        }
    }
    // 1011 0110
    // 1001 1101
    powerCheck() {
        local currently = isPowered;
        isPowered = true;
        if (!powerCable.squareAttached) isPowered = nil;
        if (!powerCable.roundAttached) isPowered = nil;
        if (!swA.isOn) isPowered = nil;
        if (swB.isOn) isPowered = nil;
        if (!swC.isOn) isPowered = nil;
        if (!swD.isOn) isPowered = nil;
        if (swE.isOn) isPowered = nil;
        if (!swF.isOn) isPowered = nil;
        if (!swG.isOn) isPowered = nil;
        if (swH.isOn) isPowered = nil;
        if (!swI.isOn) isPowered = nil;
        if (swJ.isOn) isPowered = nil;
        if (swK.isOn) isPowered = nil;
        if (!swL.isOn) isPowered = nil;
        if (!swM.isOn) isPowered = nil;
        if (!swN.isOn) isPowered = nil;
        if (swO.isOn) isPowered = nil;
        if (!swP.isOn) isPowered = nil;
        if ((currently == true) && (isPowered == nil)) {
            roaringNoise.moveInto(nil);
            dragonHead.showTeeth(nil);
            "<.p>The junction box ceases to hum. ";
        }
        else if ((currently == nil) && (isPowered == true)) {
            if (hvacSwitch.isOn) roaringNoise.moveInto(utilityRoom);
            if ((fileRoom.blockedByStuffy) && (hvacSwitch.isOn)) {
                fileRoom.blockedByStuffy = nil;
                fileRoom.blockedByBlizzard = true;
                roaringNoise.moveInto(utilityRoom);
                dragonHead.showTeeth(true);
            }
            powerAch.awardPointsOnce();
            "<.p>The junction box begins to hum gently. ";
        }
    }
;

+ boxHinge: Component, Decoration 'hinge;; hinges'
    subLocation = &remapOn
;

++ pluralSwitches: CollectiveGroup 'switches'
    collectiveActions = [Feel, Examine, Smell]
    dobjFor(Feel) {
        verify() {}
        check() { "You feel nothing unexpected. "; }
    }
    dobjFor(Examine) {
        verify() {}
        action() {
            "The switches are in two rows of eight switches each; the top row is
            lettered A through H, the bottom row I through P. Evidently each of them
            can be switched up or down. At present, they look like this:<.p> ";
            connectorPanel.showSwitches();
        }
    }
;

+ connectorPanel: Thing 'connector panel'
    "The connector panel has two jacks, <<describeCable()>> and
    two horizontal rows of switches. <<switchRows.desc()>> "
    hideFromAll(action) {
        if (action == Take) return true;
        else return inherited(action);
    }
    subLocation = &remapIn
    describeCable() {
        "one round and one square, ";
        local rndConn = powerCable.roundAttached;
        local sqrConn = powerCable.squareAttached;
        if (rndConn && sqrConn) {
            "into which the ends of a cable have been
            cleverly and firmly inserted, ";
            return;
        }
        else if (rndConn) "a cable having been inserted into and now dangling from the round jack,";
        else if (sqrConn) "a cable having been inserted into and now dangling from the square jack,";
    }
    dobjFor(Take) {
        verify() {
            illogical ('The panel is part of the junction box. ');
        }
    }
    switchList = [swA, swB, swC, swD, swE, swF, swG, swH, swI, swJ, swK, swL, swM, swN, swO, swP]
    showSwitches() {
        local ndx = 0;
        if (me.visual) {
            "<font face='TADS-Typewriter'>";
                while (ndx < 16) {
                ndx++;
                if (switchList[ndx].isOn) "+"; else "-";
                if (ndx != 8) " "; else "<.p>";
            }
            "</font>";
        }
        // else words for the blind:
        else {
            ndx = 0;
            "Switches in the top row are:\b ";
             while (ndx < 16) {
                ndx++;
                if (switchList[ndx].isOn) "up\ "; else "down\ ";
                if (ndx != 8) "\ "; else "\bSwitches in the lower row are:\b ";
            }
        }
    }
;

++ swA: JunctionSwitch '+; A'
    letter = 'A'
;
++ swB: JunctionSwitch '+; B'
    letter = 'B'
;
++ swC: JunctionSwitch '+; C'
    letter = 'C'
;
++ swD: JunctionSwitch '+; D'
    letter = 'D'
;
++ swE: JunctionSwitch '+; E'
    letter = 'E'
;
++ swF: JunctionSwitch '+; F'
    letter = 'F'
;
++ swG: JunctionSwitch '+; G'
    letter = 'G'
;
++ swH: JunctionSwitch '+; H'
    letter = 'H'
;
++ swI: JunctionSwitch '+; I'
    letter = 'I'
;
++ swJ: JunctionSwitch '+; J'
    letter = 'J'
;
++ swK: JunctionSwitch '+; K'
    letter = 'K'
;
++ swL: JunctionSwitch '+; L'
    letter = 'L'
;
++ swM: JunctionSwitch '+; M'
    letter = 'M'
;
++ swN: JunctionSwitch '+; N'
    letter = 'N'
;
++ swO: JunctionSwitch '+; O'
    letter = 'O'
;
++ swP: JunctionSwitch '+; P'
    letter = 'P'
;

++ switchRows: CollectiveGroup 'rows of switches;;; them'
    desc () {
        "There are eight switches in each row. The upper row is labeled with the letters
        A through H, the lower row with the letters I through P.
        At present, the switches are set like this:<.p>
        <<connectorPanel.showSwitches()>> ";
    }
;

++ squareJack: RestrictedContainer, Fixture 'square jack; multipin; hole'
    "It\'s a square multipin jack.<<if (powerCable.squareAttached)>> A short,
    thick cable has been plugged into it.<<end>> "
    allowedContents = [squareConnector, powerCable]
    iobjFor(AttachTo) asIobjFor(PutIn)
    iobjFor(PlugInto) asIobjFor(PutIn)
    notifyInsert(obj) {
        inherited(obj);
        if (obj == powerCable) {
            "You'll need to say which end of the cable you want to put into
            the jack. ";
            exit;
        }
//        if ((obj == squareConnector) && squareConnector.isBent) {
//            "The connector is obviously the right shape, but even so, it doesn't
//            seem to want to fit neatly into the jack. ";
//            exit;
//        }
    }
    iobjFor(PutIn) {
        verify() {}
        check() {
            if ((gDobj != squareConnector) && (gDobj != powerCable)) "That doesn\'t fit into the jack. ";
        }
    }
;

++ roundJack: RestrictedContainer, Fixture 'round jack; multipin; hole'
    "It\'s a round multipin jack.<<if (powerCable.roundAttached)>> A short,
    thick cable has been plugged into it.<<end>> "
    allowedContents = [roundConnector, powerCable]
    iobjFor(AttachTo) asIobjFor(PutIn)
    iobjFor(PlugInto) asIobjFor(PutIn)
    notifyInsert(obj) {
        inherited(obj);
        if (obj == powerCable) {
            "You'll need to say which end of the cable you want to put into
            the jack. ";
            exit;
        }
    }
    iobjFor(PutIn) {
        verify() {}
        check() {
            if ((gDobj != roundConnector)  && (gDobj != powerCable)) "That doesn\'t fit into the jack. ";
        }
    }
;

// 1011 0110
// 1001 1101
