 const int minutesLen = maxRadius - 13;
 const int hoursLen = maxRadius - 22;
 void clockScene(bool changed) {
-		if (changed) {
-				TV.draw_circle(WIDTH / 2, HEIGHT / 2, maxRadius, 1, 0);
-
-				currentAngle = random(60) * angleDiff;
-				hourAngle = random(60) * angleDiff;
-				minuteAngle = random(60) * angleDiff;
-		}
-
-		drawLineAngle(WIDTH / 2, HEIGHT / 2, currentAngle, secondsLen, 0);
-		drawLineAngle(WIDTH / 2, HEIGHT / 2, minuteAngle, minutesLen, 0);
-
-		currentAngle -= angleDiff;
-		minuteAngle -= angleDiff / 60.0;
-		// Dont bother updating hours
-
-		drawLineAngle(WIDTH / 2, HEIGHT / 2, currentAngle, secondsLen, 1);	
-		drawLineAngle(WIDTH / 2, HEIGHT / 2, hourAngle, hoursLen, 1);
-		drawLineAngle(WIDTH / 2, HEIGHT / 2, minuteAngle, minutesLen, 1);
-
-		checkSceneEnded(15);
+    if (changed) {
+        TV.draw_circle(WIDTH / 2, HEIGHT / 2, maxRadius, 1, 0);
+
+        currentAngle = random(60) * angleDiff;
+        hourAngle = random(60) * angleDiff;
+        minuteAngle = random(60) * angleDiff;
+    }
+
+    drawLineAngle(WIDTH / 2, HEIGHT / 2, currentAngle, secondsLen, 0);
+    drawLineAngle(WIDTH / 2, HEIGHT / 2, minuteAngle, minutesLen, 0);
+
+    currentAngle -= angleDiff;
+    minuteAngle -= angleDiff / 60.0;
+    // Dont bother updating hours
+
+    drawLineAngle(WIDTH / 2, HEIGHT / 2, currentAngle, secondsLen, 1);  
+    drawLineAngle(WIDTH / 2, HEIGHT / 2, hourAngle, hoursLen, 1);
+    drawLineAngle(WIDTH / 2, HEIGHT / 2, minuteAngle, minutesLen, 1);
+
+    checkSceneEnded(15);
 }
 
 double chartRayLen = 0;
 void chartScene(bool changed) {
-		const int chartRadius = (HEIGHT / 2) - 6;
-		if (changed) {
-				chartRayLen = 0;
-				TV.draw_circle(WIDTH / 2, HEIGHT / 2, chartRadius, 1, 0);
-				TV.draw_circle(WIDTH / 2, HEIGHT / 2, chartRadius - 7, 1, 0);
-				TV.draw_circle(WIDTH / 2, HEIGHT / 2, 12, 1, 0);
-
-				for (int i = 0; i < 12; i++) {
-						drawLineAngle(WIDTH / 2, HEIGHT / 2, i * (360.0 / 12), chartRadius, 1);
-				}
-
-				TV.delay(2000);
-		}
-
-		int rays = random(2, 7);
-		double offset = random(180);
-		for (int i = 0; i < rays; i++) {
-				drawLineAngle(WIDTH / 2, HEIGHT / 2, (i * (360.0 / rays)) + offset, chartRayLen + (chartRadius / 2), 1);
-		}
-
-		TV.delay(50);
-		chartRayLen += 0.2;
-
-		checkSceneEnded(20);
+    const int chartRadius = (HEIGHT / 2) - 6;
+    if (changed) {
+        chartRayLen = 0;
+        TV.draw_circle(WIDTH / 2, HEIGHT / 2, chartRadius, 1, 0);
+        TV.draw_circle(WIDTH / 2, HEIGHT / 2, chartRadius - 7, 1, 0);
+        TV.draw_circle(WIDTH / 2, HEIGHT / 2, 12, 1, 0);
+
+        for (int i = 0; i < 12; i++) {
+            drawLineAngle(WIDTH / 2, HEIGHT / 2, i * (360.0 / 12), chartRadius, 1);
+        }
+
+        TV.delay(2000);
+    }
+
+    int rays = random(2, 7);
+    double offset = random(180);
+    for (int i = 0; i < rays; i++) {
+        drawLineAngle(WIDTH / 2, HEIGHT / 2, (i * (360.0 / rays)) + offset, chartRayLen + (chartRadius / 2), 1);
+    }
+
+    TV.delay(50);
+    chartRayLen += 0.2;
+
+    checkSceneEnded(20);
 }
 
 void loop() {
-		bool changed = false;
-		if (currentScene != lastScene) {
-				TV.clear_screen();
-				TV.set_cursor(0, 0);
-
-				digitalWrite(LED_PIN, HIGH);
-				TV.delay(100);
-				digitalWrite(LED_PIN, LOW);
-
-				startTime = TV.millis();
-				changed = true;
-		}
-
-		lastScene = currentScene;
-
-		switch (currentScene) {
-				case SYMBOL_TAURUS:
-						tauroSymbolScene();
-						break;
-				case SYMBOLS_FAST:
-						fastSymbolsScene();
-						break;
-				case PLANETS_SYMBOLS_FAST:
-						planetSymbolsFastScene();
-						break;
-				case WORDS_FAST:
-						fastWordsScene();
-						break;
-				case WORDS_FAST_INLINE:
-						wordsFastInlineScene();
-						break;
-				case STARS:
-						starsScene();
-						break;
-				case NOISE:
-						noiseScene();
-						break;
-				case SYMBOL_FADE:
-						symbolFadeScene(changed);
-						break;
-				case SYMBOL_CHECKERBOARD:
-						symbolCheckerboardScene(changed);
-						break;
-				case SYMBOL_GLITCH_SIZE:
-						symbolGlitchSizeScene();
-						break;
-				case CONSTELLATIONS:
-						constellationsScene();
-						break;
-				case COMMANDS:
-						commandsScene();
-						break;
-				case SYMBOL_GLITCH_LOAD:
-						symbolGlitchLoadScene(changed);
-						break;
-				case WORD_CURSOR:
-						wordCursorScene(changed);
-						break;
-				case WORMHOLE:
-						wormholeScene(changed);
-						break;
-				case SYMBOLS_SNAKE:
-						symbolsSnakeScene(changed);
-						break;
-				case SCROLL_STARS:
-						scrollStarsScene(changed);
-						break;
-				case EYES:
-						eyesScene(changed);
-						break;
-				case CHANNEL:
-						channelScene(changed);
-						break;
-				case VHS:
-						vhsScene(changed);
-						break;
-				case SYMBOL_SHIFT:
-						symbolShiftScene(changed);
-						break;
-				case BLINDS:
-						blindsScene(changed);
-						break;
-				case FADE_IN:
-						fadeInScene(changed);
-						break;
-				// case WHITE_BEAR:
-				// 		whiteBearScene(changed);
-				// 		break;
-				case PARTY_WORDS:
-						partyWordsScene();
-						break;
-				case FILL_LINES:
-						fillLinesScene(changed);
-						break;
-				case CIRCLES:
-						circlesScene(changed);
-						break;
-				case L_SYSTEM:
-						lSystemScene();
-						break;
-				case CLOCK:
-						clockScene(changed);
-						break;
-				case CHART:
-						chartScene(changed);
-						break;
-        		case HEX_SCENE:
-            			hexScene(changed);
-            			break;
-				case PYRAMID:
-						pyramidScene(changed);
-						break;
-				default:
-						TV.print("Invalid scene. ");
-						TV.delay(1000);
-						break;
-		}
-}
+    bool changed = false;
+    if (currentScene != lastScene) {
+        TV.clear_screen();
+        TV.set_cursor(0, 0);
+
+        digitalWrite(LED_PIN, HIGH);
+        TV.delay(100);
+        digitalWrite(LED_PIN, LOW);
+
+        startTime = TV.millis();
+        changed = true;
+    }
+
+    lastScene = currentScene;
+
+    switch (currentScene) {
+        case SYMBOL_TAURUS:
+            tauroSymbolScene();
+            break;
+        case SYMBOLS_FAST:
+            fastSymbolsScene();
+            break;
+        case PLANETS_SYMBOLS_FAST:
+            planetSymbolsFastScene();
+            break;
+        case WORDS_FAST:
+            fastWordsScene();
+            break;
+        case WORDS_FAST_INLINE:
+            wordsFastInlineScene();
+            break;
+        case STARS:
+            starsScene();
+            break;
+        case NOISE:
+            noiseScene();
+            break;
+        case SYMBOL_FADE:
+            symbolFadeScene(changed);
+            break;
+        case SYMBOL_CHECKERBOARD:
+            symbolCheckerboardScene(changed);
+            break;
+        case SYMBOL_GLITCH_SIZE:
+            symbolGlitchSizeScene();
+            break;
+        case CONSTELLATIONS:
+            constellationsScene();
+            break;
+        case COMMANDS:
+            commandsScene();
+            break;
+        case SYMBOL_GLITCH_LOAD:
+            symbolGlitchLoadScene(changed);
+            break;
+        case WORD_CURSOR:
+            wordCursorScene(changed);
+            break;
+        case WORMHOLE:
+            wormholeScene(changed);
+            break;
+        case SYMBOLS_SNAKE:
+            symbolsSnakeScene(changed);
+            break;
+        case SCROLL_STARS:
+            scrollStarsScene(changed);
+            break;
+        case EYES:
+            eyesScene(changed);
+            break;
+        case CHANNEL:
+            channelScene(changed);
+            break;
+        case VHS:
+            vhsScene(changed);
+            break;
+        case SYMBOL_SHIFT:
+            symbolShiftScene(changed);
+            break;
+        case BLINDS:
+            blindsScene(changed);
+            break;
+        case FADE_IN:
+            fadeInScene(changed);
+            break;
+        case PARTY_WORDS:
+            partyWordsScene();
+            break;
+        case FILL_LINES:
+            fillLinesScene(changed);
+            break;
+        case CIRCLES:
+            circlesScene(changed);
+            break;
+        case L_SYSTEM:
+            lSystemScene();
+            break;
+        case CLOCK:
+            clockScene(changed);
+            break;
+        case CHART:
+            chartScene(changed);
+            break;
+        case HEX_SCENE:
+            hexScene(changed);
+            break;
+        case PYRAMID:
+            pyramidScene(changed);
+            break;
+        default:
+            TV.print("Invalid scene. ");
+            blinkForever();
+            break;
+    }
+}

int snakeY = HEIGHT / 2;
unsigned long lastReset = 0;
void symbolsSnakeScene(bool changed) {
		if (changed) {
				lastSnakeBmp = getRandomSymbol();

				TV.bitmap(BMP_X, BMP_Y, lastSnakeBmp);
				
				lastReset = TV.millis();
				snakeX = WIDTH / 2;
				snakeY = HEIGHT / 2;
		}

		if (TV.millis() - lastReset > 2000) {
				TV.clear_screen();
				TV.bitmap(BMP_X, BMP_Y, lastSnakeBmp);
				lastReset = TV.millis();
				snakeX = WIDTH / 2;
				snakeY = HEIGHT / 2;
				orientation = random((int)TOTAL_ORIENTATION);
		}

		unsigned char currentColor = TV.get_pixel(snakeX, snakeY);
		TV.set_pixel(snakeX, snakeY, !currentColor);

		switch (orientation) {
				case Tau_NE:
					snakeY--;
					snakeX++;
				break;
				case Tau_SE:
					snakeY++;
					snakeX++;
				break;
				case Tau_SW:
					snakeX--;
					snakeY++;
				break;
				case Tau_NW:
					snakeX--;
					snakeY--;
				break;
		}

		if (snakeX < 0) {
				snakeX = WIDTH;
		} else if (snakeX > WIDTH) {
				snakeX = 0;
		}

		if (snakeY < 0) {
				snakeY = HEIGHT;
		} else if (snakeY > HEIGHT) {
				snakeY = 0;
		}

		unsigned char newColor = TV.get_pixel(snakeX, snakeY);

		if (newColor != currentColor) {
				orientation = orientation + 1;
				orientation = orientation % TOTAL_ORIENTATION;
		}

		checkSceneEnded(20);
}

void scrollStarsScene(bool changed) {
		if (changed) {
				// Draw the earth
				TV.draw_circle(WIDTH / 2, HEIGHT / 2, HEIGHT / 2, WHITE, WHITE);
		}

		TV.shift(1, 1);

		// Place a new star on top line
		if (random(7) == 0) {
				TV.set_pixel(random(WIDTH), 0, 1);
		}

		TV.delay(100);

		if (checkSceneEnded(12)) {
				TV.delay(1000);
		}
}

void eyesScene(bool changed) {
		TV.bitmap(BMP_X, BMP_Y, open_eye);

		int irisRadius = 6;
		int irisOffset = -irisRadius + random(irisRadius * 2);
		TV.draw_circle((WIDTH / 2) + irisOffset, HEIGHT / 2, irisRadius, 1, 1);

		TV.delay(1200);

		TV.bitmap(BMP_X, BMP_Y, closed_eye);

		TV.delay(random(200, 600));

		checkSceneEnded(20);
}

void channelScene(bool changed) {
		if (changed) {
				char *s = "VIDEO 1";
				TV.set_cursor(WIDTH - (strlen(s) * FONT_W) - 2, FONT_H + 2);
				TV.print(s);
		}

		TV.delay(1);

		checkSceneEnded(8);
}

int vhsTime = 0;
void vhsScene(bool changed) {
		char *stop = "STOP";
		char *play = "PLAY";
		const int timerWidth = 5;
		char *timer = "--:--";

		if (changed) {
				vhsTime = 0;
				TV.set_cursor(2, FONT_H + 2);
				TV.print(stop);

				TV.set_cursor(WIDTH - (timerWidth * FONT_W) - 2, FONT_H + 2);
				TV.print(timer);

				TV.delay(3500);
				TV.clear_screen();

				TV.set_cursor(2, FONT_H + 2);
				TV.print(play);

				return;
		}

		TV.set_cursor(WIDTH - (timerWidth * FONT_W) - 2, FONT_H + 2);
		TV.print("00:0");
		TV.print(vhsTime % 10);
		vhsTime++;

		TV.delay(1000);

		checkSceneEnded(9);
}

void shiftLine(int orientation, int direction, int index, int step) {
		if (orientation == 0) {
				// Shift column
				if (direction == 1) {
						for (int i = HEIGHT - 2; i >= 0; i--) {
								unsigned char pix = TV.get_pixel(index, i);
								TV.set_pixel(index, i + step, pix);
						}
				} else {
						for (int i = 1; i <= HEIGHT - 1; i++) {
								unsigned char pix = TV.get_pixel(index, i);
								TV.set_pixel(index, i - step, pix);
						}		
				}
		} else {
				// Shift row
				if (direction == 1) {
						for (int i = WIDTH - 2; i >= 0; i--) {
								unsigned char pix = TV.get_pixel(i, index);
								TV.set_pixel(i + step, index, pix);
						}
				} else {
						for (int i = 1; i <= WIDTH - 1; i++) {
								unsigned char pix = TV.get_pixel(i, index);
								TV.set_pixel(i - step, index, pix);
						}		
				}			
		}
}

#define STEP_COUNT 300

#define LED_PIN 13

enum Scene {
    SYMBOL_TAURUS = 0,
    SYMBOLS_FAST,
    PLANETS_SYMBOLS_FAST,
    WORDS_FAST,
    WORDS_FAST_INLINE,
    STARS,
    NOISE,
    SYMBOL_FADE,
    SYMBOL_CHECKERBOARD,
    SYMBOL_GLITCH_SIZE,
    SYMBOL_GLITCH_LOAD,
    CONSTELLATIONS,
    COMMANDS,
    WORD_CURSOR,
    WORMHOLE,
    SYMBOLS_SNAKE,
    SCROLL_STARS,
    EYES,
    CHANNEL,
    VHS,
    SYMBOL_SHIFT,
    BLINDS,
    FADE_IN,
    PARTY_WORDS,
    FILL_LINES,
    CIRCLES,
    L_SYSTEM,
    CLOCK,
    CHART,
    HEX_SCENE,
    PYRAMID,
    TOTAL
};

Scene currentScene = PYRAMID; // Initial scene
