#include <FastLED.h>

#define NUM_LEDS 212
//****************************
#define DATA_PIN 6
const char* zero =   "####"
                     "#..#"
                     "#..#"
                     "#..#"
                     "#..#"
                     "#..#"
                     "####";

const char* one =    "...#" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#";

const char* two =    "####" 
                     "...#" 
                     "...#" 
                     "####" 
                     "#..." 
                     "#..." 
                     "####";

const char* three =  "####" 
                     "...#" 
                     "...#" 
                     "####" 
                     "...#" 
                     "...#" 
                     "####";

const char* four =   "#..#" 
                     "#..#" 
                     "#..#" 
                     "####" 
                     "...#" 
                     "...#" 
                     "...#";

const char* five =   "####" 
                     "#..." 
                     "#..." 
                     "####" 
                     "...#" 
                     "...#" 
                     "####";

const char* six =    "#..." 
                     "#..." 
                     "#..." 
                     "####" 
                     "#..#" 
                     "#..#" 
                     "####";

const char* seven =  "####" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#" 
                     "...#";

const char* eight =  "####" 
                     "#..#" 
                     "#..#" 
                     "####" 
                     "#..#" 
                     "#..#" 
                     "####";

const char* nine =   "####" 
                     "#..#" 
                     "#..#" 
                     "####" 
                     "...#" 
                     "...#" 
                     "####";
const char* numberConfigs[] {zero, one, two, three, four, five, six, seven, eight, nine};

struct DigitElement
{
   int baseOffset;
   bool hasOneHundred;
   int segmentedDigitCount;
};
struct IndicatorElement
{
  int baseOffset;
  int lightCount;
};

DigitElement homeScore = {0, true, 2};
DigitElement visitorScore = {127, true, 2};
DigitElement timeMinutes = {47, false, 2};
DigitElement timeSeconds = {87, false, 2};
DigitElement period = {183, false, 1};

IndicatorElement homeBonus = {209, 3};
IndicatorElement visitorBonus = {174, 3};
IndicatorElement homePosession = {203, 6};
IndicatorElement visitorPosession = {177, 6};

CRGB leds[NUM_LEDS]; 
CRGB onColor = CRGB::White;
CRGB offColor = CRGB::Black;

void stringToDigit(char* str, int ledStartIndex)
{
  stringToDigit(str, ledStartIndex, onColor);
}
void stringToDigit(char* str, int ledStartIndex, CRGB colorOverride)
{
  leds[ledStartIndex]    = str[0]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+1]  = str[1]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+2]  = str[2]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+3]  = str[3]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+4]  = str[7]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+5]  = str[4]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+6]  = str[8]  == '#' ? colorOverride : offColor;
  leds[ledStartIndex+7]  = str[11] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+8]  = str[15] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+9]  = str[14] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+10] = str[13] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+11] = str[12] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+12] = str[16] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+13] = str[19] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+14] = str[23] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+15] = str[20] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+16] = str[24] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+17] = str[25] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+18] = str[26] == '#' ? colorOverride : offColor;
  leds[ledStartIndex+19] = str[27] == '#' ? colorOverride : offColor;
}

//*****************************************************
void updateDigit(DigitElement el, int value)
{
  updateDigit(el, value, onColor);
}
void updateDigit(DigitElement el, int value, CRGB colorOverride)
{
  int currentRoot = el.baseOffset;
  if (el.hasOneHundred)
  {
    CRGB hundred = (value > 99) ? colorOverride : offColor;

    for (int i = currentRoot; i < currentRoot + 7; i++) 
    {
      leds[i] = hundred;
    }
    currentRoot += 7;
  }
  if (el.segmentedDigitCount > 1)
  {
    int tensIndex = (value / 10) % 10;
    stringToDigit(numberConfigs[tensIndex], currentRoot, colorOverride);
    currentRoot += 20;
  }
  int onesIndex = (value % 10);
  stringToDigit(numberConfigs[onesIndex], currentRoot, colorOverride);
}
void updateIndicator(IndicatorElement el, bool value)
{
  updateIndicator(el, value, onColor);
}
void updateIndicator(IndicatorElement el, bool value, CRGB colorOverride)
{
   for (int i = el.baseOffset; i < el.baseOffset + el.lightCount; i++) {
     leds[i] = value ? colorOverride : offColor;
   }
}

//********************************************************
int nPeriod = 1;
int seconds = 0; 
int nHomeScore = 0;
int nVisitorScore = 0;
bool bTimeRunning = false;
int bonus = 0; // -1 home; 0 none; 1 visitors
bool posession = 0; // 0 home; 1 visitors

void updateScoreboard()
{
  nHomeScore = constrain(nHomeScore, 0, 199);
  nVisitorScore = constrain(nVisitorScore, 0, 199);
  nPeriod = constrain(nPeriod, 0, 9);
  seconds = constrain(seconds, 0, 3600);
  int minutesCalc = seconds / 60;
  int secondsCalc = seconds % 60;
  updateDigit(homeScore, nHomeScore, CRGB::DarkRed);
  updateDigit(visitorScore, nVisitorScore, CRGB::DarkRed);
  updateDigit(period, nPeriod, CRGB::LimeGreen);
  updateDigit(timeMinutes, minutesCalc, CRGB::FairyLight);
  updateDigit(timeSeconds, secondsCalc, CRGB::FairyLight);

  updateIndicator(homePosession, posession == 0);
  updateIndicator(visitorPosession, posession == 1);
  updateIndicator(homeBonus, bonus == -1);
  updateIndicator(visitorBonus, bonus == 1);

  FastLED.show();
}

void HomeScoreUp1() {
  nHomeScore++;
}
void HomeScoreReset() {
  nHomeScore = 0;
}
void HomeScoreDown1() {
    nHomeScore--;
}
void PeriodUp() {
  nPeriod++;
  if (nPeriod > 4)
  {
    nPeriod = 1;
  }
}
void VisitorScoreDown1() {
  nVisitorScore--;
}
void VisitorScoreReset() {
  nVisitorScore = 0;
}
void VisitorScoreUp1() {
  nVisitorScore++;
}
void HomeBonus() {
  bonus = (bonus == -1) ? 0 : -1;
}
void HomePos() {
  posession = 0;
}
void VisitorPos() {
  posession = 1;
}
void VisitorBonus() {
  bonus = (bonus == 1) ? 0 : 1;
}
void StartStopTimer() {
  bTimeRunning = !bTimeRunning;
}
void TimeDn1() {
  seconds--;
}
void TimeDn10() {
  seconds-=10;
}
void TimeDn60() {
  seconds-=60;
}
void TimeUp60() {
  seconds+=60;
}
void TimeUp10() {
  seconds+=10;
}
void TimeUp1() {
  seconds++;
}
void TimerSet12() {
  seconds = 720;
}
void TimerSet10() {
  seconds = 600;
}
void TimerSet0() {
  seconds = 0;
}
void TimerSet2() {
  seconds = 120;
}
void TimerSet20() {
  seconds = 1200;
}
void Buzzer() {
  // TODO:
  Serial.println("Zzzzzt!");
}

//********************************************************
void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  Serial.begin(9600);
  // TEMP FOR TESTING
  TimerSet2();
  StartStopTimer();
  //_________________
}
void loop() {

  // TEMP FOR TESTING
  if (nHomeScore == 0)
  {
    nHomeScore = 199;
  }
  nVisitorScore = 199 - nHomeScore;
  HomeScoreDown1();
  PeriodUp();
  //_________________

  if (bTimeRunning)
  {
    seconds--;
    if (seconds == 0)
    {
      bTimeRunning = false;
      Buzzer();
    }
  }
  updateScoreboard();
  delay(1000);
}
Shot timer.
Home Team Score.
Visitor Team Score.
Current period.
Visitor Posession.
Home Team Posession.
Home Team Bonus.
Visitor Team Bonus.