// Program to show full catalog of the MD_Parola animations
//
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Servo.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 3
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

Servo myservo;  // create servo object to control a servo
int position = 0;    // variable to store the servo position
boolean forward = false ;   // state variable
unsigned long ts = millis () ;   // time accounting.
#define DELAY 100
// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Global data
struct sCatalog
{
  textEffect_t  effect;   // text effect to display
  const char *  psz;      // text string nul terminated
  uint16_t      speed;    // speed multiplier of library default
  uint16_t      pause;    // pause multiplier for library default
};

sCatalog catalog[] =
{
  //{ PA_PRINT, "oHai", 100, 1 },
  //{ PA_SCROLL_UP, "SC_U", 50, 1 },
  //{ PA_SCROLL_DOWN, "SCR_D", 50, 1 },
  //
 // { PA_SCROLL_LEFT, "Featuring Pwnton-agotchi and Neutrona Wand Deauther", 20, 1 },
#if ENA_SPRITE
  { PA_SPRITE, "", 10, 1 },
  { PA_SCROLL_LEFT, "The Pwnton Pack", 10, 1 },
  
  { PA_SCROLL_LEFT, "Follow:", 10, 1 },
  { PA_SCROLL_LEFT, "W9HAX", 20, 1 },
  { PA_SCROLL_RIGHT, "WiFi Hacks", 10, 1 },

  { PA_SPRITE, "Pwn'd", 10, 1 },
#endif
};

// Sprite Definitions
const uint8_t F_GHOST = 2;
const uint8_t W_GHOST = 7;
static const uint8_t PROGMEM ghost[F_GHOST * W_GHOST] =
{
 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
};

const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
static const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] =  // gobbling pacman animation
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
};

const uint8_t F_PMAN2 = 6;
const uint8_t W_PMAN2 = 18;
static const uint8_t PROGMEM pacman2[F_PMAN2 * W_PMAN2] =  // ghost pursued by a pacman
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
};

void setup(void)
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  P.begin();
#if ENA_SPRITE
  P.setSpriteData(ghost, W_GHOST, F_GHOST, ghost, W_GHOST, F_GHOST);
#endif

  for (uint8_t i=0; i<ARRAY_SIZE(catalog); i++)
  {
    catalog[i].speed *= P.getSpeed();
    catalog[i].pause *= 500;
  }
}

void loop(void)
{

  if (millis () - ts >= DELAY)
  {
    ts += DELAY ;   // setup timestamp for next time.
    if (forward)
    {
      myservo.write (-- position) ;  // progress the servo
      if (position == 0)  // test for reverse
        forward = false ;
    }
    else
    {
      myservo.write (++ position) ;  // progress the servo
      if (position == 180)  // test for reverse
        forward = true ;
    }
  }

  
  //MATRIX
  
  static textPosition_t just = PA_LEFT;
  static uint8_t i = 0;   // text effect index
  static uint8_t j = 0;   // text justification index

  if (P.displayAnimate()) // animates and returns true when an animation is completed
  {
    // progress the justification if needed
    if (i == ARRAY_SIZE(catalog))
    {
      j++;
      if (j == 3) j = 0;

      switch (j)
      {
      case 0: just = PA_LEFT;    break;
      case 1: just = PA_CENTER;  break;
      case 2: just = PA_RIGHT;   break;
      }

      i = 0;  // reset loop index
    }

    // set up new animation
    P.displayText(catalog[i].psz, just, catalog[i].speed, catalog[i].pause, catalog[i].effect, catalog[i].effect);

    i++;   // then set up for next text effect
  }
}