// The sun.

// A possibly failed experiment. Wanted to have a fire radial without a big array.

// Thought was to use decaying perlin noise from the center and to draw a number of lines around the
// circle from the center.

// Back to the drawing board.


#include <FastLED.h>

#define LED_PIN  3
#define COLOR_ORDER       GRB
#define CHIPSET           WS2812B
#define kMatrixWidth      20
#define kMatrixHeight     20
#define kMatrixSerpentine true
#define kMatrixRowMajor   true
#define kMatrixFlipMajor  true
#define kMatrixFlipMinor  false
#define NUM_LEDS          ((kMatrixWidth) * (kMatrixHeight))
#define kHalfWidth        (kMatrixWidth / 2)
#define kHalfHeight       (kMatrixHeight / 2)

CRGBPalette16 currentPalette;

CRGB leds_plus_safety_pixel[NUM_LEDS + 1];
CRGB* const leds(leds_plus_safety_pixel + 1);



void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);

  currentPalette = CRGBPalette16( CRGB::Yellow, CRGB::Yellow, CRGB::Orange,CRGB::Yellow,
                                 CRGB::Orange, CRGB::Orange,CRGB::DarkOrange,CRGB::DarkOrange,
                                CRGB::Red, CRGB::Red, CRGB::Red, CHSV(0, 255, 16),
                                   CHSV(0, 255, 8), CHSV(0,255,8), CHSV(0,255,4), CHSV(0,255,2));


// drawCircle();
}


void loop() {
//  drawFrame();
//  inoise8_fire();
  fire_circle();
  FastLED.show();
}


void drawCircle() {
//  for (float i = 0; i < 2*3.14159; i=i+3.14159/200) {
//    uint16_t x = kMatrixWidth/2 * cos(i) + kMatrixWidth/2;
//    uint16_t y = kMatrixWidth/2 * sin(i) + kMatrixWidth/2;
//    leds[XY(x,y)] = CRGB::White;
//  }

  for (float i = 0; i < 2*3.14159; i=i+3.14159/32) {
    for (int rad = 0; rad < kMatrixWidth/2; rad++) {
      uint16_t x = rad * cos(i) + kMatrixWidth/2;
      uint16_t y = rad * sin(i) + kMatrixWidth/2;
      leds[XY(x,y)] = CRGB::White;    
    }
  }
}


void fire_circle() {

  uint32_t xscale = 20;                                          // How far apart they are
  uint32_t yscale = 3;                                           // How fast they move
  uint8_t index;

//  for (float i = 0; i < 2*3.14159; i=i+3.14159/32) {
  for (float i = 0; i < 360; i=i+1) {


    for (int rad = 0; rad < kMatrixWidth/2; rad++) {
      uint16_t x = rad * cos(i) + kMatrixWidth/2;
      uint16_t y = rad * sin(i) + kMatrixWidth/2;

      index = inoise8(rad*20*xscale,millis()*yscale*NUM_LEDS/255);                                          // X location is constant, but we move along the Y at the rate of millis()
      leds[XY(x,y)] = ColorFromPalette(currentPalette, min((int)rad*(index)>>4, 255), 255 - (rad*255/kMatrixWidth/2), LINEARBLEND);  // With that value, look up the 8 bit colour palette value and assign it to the current LED.    
    }

  }



}




void inoise8_fire() {
 
  uint32_t xscale = 20;                                          // How far apart they are
  uint32_t yscale = 3;                                           // How fast they move
  uint8_t index;
  
  for (int i = 0; i < 16; i++) {
    index = inoise8(i*xscale,millis()*yscale*NUM_LEDS/255);                                           // X location is constant, but we move along the Y at the rate of millis()
      leds[i] = ColorFromPalette(currentPalette, min(i*(index)>>4, 255), 255 - i*255/16, LINEARBLEND);  // With that value, look up the 8 bit colour palette value and assign it to the current LED.  

  }                                                                                                   // The higher the value of i => the higher up the palette index (see palette definition).
                                                                                                      // Also, the higher the value of i => the brighter the LED.
} // inoise8_fire()




int16_t XY(int8_t x, int8_t y) {
  uint8_t major, minor, sz_major, sz_minor;
  if (x >= kMatrixWidth || y >= kMatrixHeight || x < 0 || y < 0) return -1;
  if (kMatrixRowMajor)
    major = x, minor = y, sz_major = kMatrixWidth,  sz_minor = kMatrixHeight;
  else
    major = y, minor = x, sz_major = kMatrixHeight, sz_minor = kMatrixWidth;
  if (kMatrixFlipMajor ^ (minor & 1 && kMatrixSerpentine))
    major = sz_major - 1 - major;
  if (kMatrixFlipMinor)
    minor = sz_minor - 1 - minor;
  return (uint16_t) minor * sz_major + major;
}