   
   // else: val is below pot_locs[0] or greater than pot_locs[7]
   // puzzle is borken
-  sendCastleErrorMessage();
   return -1;
 }
-
-// turn on light / open solenoid for selector connection #n
-void showCorrect(int n)
-{
-  // turn on light
-  digitalWrite(output_lights[n], HIGH);
-  
-  // TODO(bhomberg): open solenoid??
-}
-
-// turn on light for gear #n lodged, or not
-void showLodged(int n, boolean isLodged)
-{
-  digitalWrite(gear_lodged[n], isLodged ? HIGH : LOW);
-}
-
-// gears have been taken out / selector gear goes back to beginning, reset everything
-void reset()
-{
-  // turn off all lights
-  for(int i=0; i<7; i++)
-  {
-    digitalWrite(output_lights[i], LOW);
-  }
-  for(int i=0; i<3; i++) 
-  {
-    digitalWrite(gear_lodged[i], LOW);
-  }
-
-  // reset internal state: you have to start over.
-  have_won = false;
-  for(int i=0; i<7; i++)
-  {
-    correct_positions[i] = 0;
-  }
-
-  // TODO(bhomberg): close all solenoids (??)
-}

  return false;
}

void sendCastleSuccessMessage() 
{
  // 20's -- 2nd puzzle message

// this is run continuously after setup has completed
void loop() 
{
  int selector_pos = getSelectorGearPosition();
  if (selector_pos == -1)
  {
    sendCastleErrorMessage();
    return;
  }

  // LE GRAND STATE MACHINE
  // NOTE: with some exceptions the state machine falls through: if we advance
  // position we immediately do what we would have done there.
  if (state == 0)
  {
    // TODO(benkraft): Should we only be starting here when the red button is
    // pressed?
    if (selector_pos == 0)
    {
      // We have started calibrating!
      state = 1;
    }
  }

  if (state == 1)
  {
    if (selector_pos < last_selector_pos
        || selector_pos > last_selector_pos + 1)
    {
      // They have gone backwards or too fast.
      // TODO(benkraft): We may wish to debounce here, or say it's ok for them
      // to go back and forth as long as they get there eventually (and we only
      // consider the position they last got to in order).
      state = 0;
      resetLights();
    }
    else if (selector_pos == last_selector_pos + 1)
    {
      // Fill in new photoresistor states.
      // TODO(benkraft): We almost certainly want to wait until we're closer to
      // the middle of this state to check; probably this will be solved at the
      // same time as debouncing.
      for (int i=0; i<3; i++)
      {
        photoresistor_history[i][selector_pos] = getPhotoresistor(i);
      }

      // If we are at the end, move on to state 2.
      if (selector_pos == 6)
      {
        state = 2;
        // This fills in gear_types and gear_orientations.
        if (!computeGearPositions())
        {
          // Or should we say you failed calibration?
          sendCastleErrorMessage();
          state = 0;
          resetLights();
        }

        for (int i=0; i<7; i++)
        {
          correct_positions[i] = false;
        }
      }
    }
  }

  if (state == 2)
  {
    if (selector_pos > last_selector_pos
        || selector_pos < last_selector_pos - 1)
    {
      // They have gone backwards or too fast.
      // TODO(benkraft): As above, we may wish to debounce.
      state = 0;
      resetLights();
    }
    else if (selector_pos == last_selector_pos - 1)
    {
      // Fill in new connection states.
      correct_positions[selector_pos] = haveConnection(selector_pos);
      if (correct_positions[selector_pos])
      {
        showCorrect(selector_pos);
      }

      if (selector_pos == 0)
      {
        // If we are back to the beginning, and have won, yay!
        boolean winning = true;
        for (int i=0; i<7; i++)
        {
          if (!correct_positions[i])
          {
            winning = false;
            break;
          }
        }

        if (winning)
        {
          state = 3;
          sendCastleSuccessMessage();
        }
      }
    }
  }

  // TODO(benkraft): How do we exit state 3?  When the button is pressed?

  last_selector_pos = selector_pos;
  delay(50);
}


// LOGIC FOR GEAR STUFF

// Takes in photoresistor_history, which must be filled in entirely, and sets
// gear_orientations and gear_types.
// Returns true for success, false if there was an issue.
boolean computeGearPositions()
{
  // TODO(benkraft)
}

// True if positions pos1 and pos2 are connected on gear_num.
