/*
 * Board:   Arduino Uno
 * Target:  PE Series on LED Effects
 * Author:  Clive "Max" Maxfield (max@clivemaxfield.com) 
 * License: The MIT License (See full license at the bottom of this file)
 *
 * Notes:   Using a single NeoPixel with a SPCO switch
 */

#include <Adafruit_NeoPixel.h>        // Library for NeoPixels

#define NUM_NEOS                         1

#define SWITCH_ON                      LOW
#define SWITCH_OFF                    HIGH

#define COLOR_WHITE              0xFFFFFFU
#define COLOR_BLACK              0x000000U

#define COLOR_RED                0xFF0000U
#define COLOR_GREEN              0x00FF00U
#define COLOR_BLUE               0x0000FFU

#define COLOR_YELLOW             0xFFFF00U
#define COLOR_CYAN               0x00FFFFU
#define COLOR_HOT_PINK           0xFF00FFU

#define COLOR_DARK_ORANGE        0xFF8000U
#define COLOR_AMBER              0xFFC000U
#define COLOR_LIME_GREEN         0xC0FF00U
#define COLOR_CHARTREUSE         0x80FF00U
#define COLOR_SPRING_GREEN       0x00FFC0U
#define COLOR_AZURE              0x0080FFU
#define COLOR_ELECTRIC_VIOLET    0x8000FFU

#define NUM_CYCLES                       1
#define CYCLE_DELAY                   2000


enum SwitchStates {
    SWITCH_NC_ACTIVE,
    SWITCH_NO_ACTIVE,
    SWITCH_CENTER
};

enum SwitchStates NewSwitchState;
enum SwitchStates OldSwitchState;


int PinSwitchNc = 3;
int PinSwitchNo = 4;

int PinNeos     =  6;

// Instantiate NeoPixel(s)
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel Neos(NUM_NEOS, PinNeos, NEO_GRB + NEO_KHZ800);


void setup ()
{
//    Serial.begin (9600);

    int switchNc;
    int switchNo;
  
    pinMode(PinSwitchNc, INPUT);
    pinMode(PinSwitchNo, INPUT);

    Neos.begin();
    Neos.show();

    for (int iCycle = 0; iCycle < NUM_CYCLES; iCycle++)
    {
        LightLed(COLOR_RED);      delay(CYCLE_DELAY);
        LightLed(COLOR_GREEN);    delay(CYCLE_DELAY);
        LightLed(COLOR_BLUE);     delay(CYCLE_DELAY);
        LightLed(COLOR_YELLOW);   delay(CYCLE_DELAY);
        LightLed(COLOR_CYAN);     delay(CYCLE_DELAY);
        LightLed(COLOR_HOT_PINK); delay(CYCLE_DELAY);
        LightLed(COLOR_WHITE);    delay(CYCLE_DELAY);
        LightLed(COLOR_BLACK);    delay(CYCLE_DELAY);
    }
  
    switchNc = digitalRead(PinSwitchNc);
    switchNo = digitalRead(PinSwitchNo);

    // The following is overkill on the conditions to make it clear what's going on
    if      ( (switchNc == SWITCH_ON)  && (switchNo == SWITCH_OFF) ) OldSwitchState = SWITCH_NC_ACTIVE;
    else if ( (switchNc == SWITCH_OFF) && (switchNo == SWITCH_ON)  ) OldSwitchState = SWITCH_NO_ACTIVE;
    else if ( (switchNc == SWITCH_OFF) && (switchNo == SWITCH_OFF) ) OldSwitchState = SWITCH_CENTER;

    // The following is overkill on the conditions to make it clear what's going on
    if (OldSwitchState == SWITCH_NC_ACTIVE)
    {
        LightLed(COLOR_GREEN);
    }
    else if (OldSwitchState == SWITCH_NO_ACTIVE)
    {
        LightLed(COLOR_RED);
    }
    else if (OldSwitchState == SWITCH_CENTER)
    {
        LightLed(COLOR_BLACK);  // Should be yellow, but use black for demo
        // LightLed(COLOR_YELLOW);
    }
}

void loop ()
{
    int switchNc;
    int switchNo;

    switchNc = digitalRead(PinSwitchNc);
    switchNo = digitalRead(PinSwitchNo);

    // The following is overkill on the conditions to make it clear what's going on
    if      ( (switchNc == SWITCH_ON)  && (switchNo == SWITCH_OFF) ) NewSwitchState = SWITCH_NC_ACTIVE;
    else if ( (switchNc == SWITCH_OFF) && (switchNo == SWITCH_ON)  ) NewSwitchState = SWITCH_NO_ACTIVE;
    else if ( (switchNc == SWITCH_OFF) && (switchNo == SWITCH_OFF) ) NewSwitchState = SWITCH_CENTER;

    if (NewSwitchState != OldSwitchState)
    {
        // The following is overkill on the conditions to make it clear what's going on
        if (NewSwitchState == SWITCH_NC_ACTIVE)
        {
            LightLed(COLOR_GREEN);
        }
        else if (NewSwitchState == SWITCH_NO_ACTIVE)
        {
            LightLed(COLOR_RED);
        }
        else if (NewSwitchState == SWITCH_CENTER)
        {
            if (OldSwitchState == SWITCH_NC_ACTIVE)
            {
                LightLed(COLOR_YELLOW);
            }
            else if (OldSwitchState == SWITCH_NO_ACTIVE)
            {
                LightLed(COLOR_DARK_ORANGE);
            }
        }
        
        OldSwitchState = NewSwitchState;
    }
}


void LightLed (unsigned long thisColor)
{
    Neos.setPixelColor(0, thisColor);
    Neos.show();
}



/*
 * Copyright (c) 2020 Clive "Max" Maxfield
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and any associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */