/*\
|*|  AvCaster - light-weight native gStreamer GUI for screencast, webcam, and audio streaming
|*|  Copyright 2015-2017 bill-auger <https://github.com/bill-auger/av-caster/issues>
|*|
|*|  This file is part of the AvCaster program.
|*|
|*|  AvCaster is free software: you can redistribute it and/or modify
|*|  it under the terms of the GNU General Public License version 3
|*|  as published by the Free Software Foundation.
|*|
|*|  AvCaster is distributed in the hope that it will be useful,
|*|  but WITHOUT ANY WARRANTY; without even the implied warranty of
|*|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
|*|  GNU General Public License for more details.
|*|
|*|  You should have received a copy of the GNU General Public License
|*|  along with AvCaster.  If not, see <http://www.gnu.org/licenses/>.
\*/


//[Headers] You can add your own extra header files here...

#include "../Constants/AppConstants.h"
#include "../Constants/GuiConstants.h"

//[/Headers]

#include "Spinner.h"


//[MiscUserDefs] You can add your own user definitions and misc code here...
//[/MiscUserDefs]

//==============================================================================
Spinner::Spinner ()
{
    //[Constructor_pre] You can add your own custom stuff here..
    //[/Constructor_pre]

    addAndMakeVisible (spinner = new DrawableImage());
    spinner->setName ("spinner");


    //[UserPreSize]

  this->t           = 0 ;
  this->sourceImage = ImageCache::getFromMemory(BinaryData::avcasterlogo128_png    ,
                                                BinaryData::avcasterlogo128_pngSize) ;
  this->targetImage = Image(Image::ARGB , GUI::SPINNER_W , GUI::SPINNER_W , true) ;

    //[/UserPreSize]

    setSize (1, 1);


    //[Constructor] You can add your own custom stuff here..
    //[/Constructor]
}

Spinner::~Spinner()
{
    //[Destructor_pre]. You can add your own custom destruction code here..
    //[/Destructor_pre]

    spinner = nullptr;


    //[Destructor]. You can add your own custom destruction code here..
    //[/Destructor]
}

//==============================================================================
void Spinner::paint (Graphics& g)
{
    //[UserPrePaint] Add your own custom painting code here..
    //[/UserPrePaint]

    g.setColour (Colour (0x80000000));
    g.fillRoundedRectangle (24.0f, 24.0f, static_cast<float> (getWidth() - 48), static_cast<float> (getHeight() - 48), 5.000f);

    //[UserPaint] Add your own custom painting code here..
    //[/UserPaint]
}

void Spinner::resized()
{
    //[UserPreResize] Add your own custom resize code here..
    //[/UserPreResize]

    spinner->setBounds ((getWidth() / 2) - (128 / 2), (getHeight() / 2) - (128 / 2), 128, 128);
    //[UserResized] Add your own custom resize handling here..
    //[/UserResized]
}



//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...

void Spinner::setVisibility(bool should_show_spinner)
{
  if (should_show_spinner) startTimerHz(GUI::SPINNER_FPS) ; else stopTimer() ;

  this->t = 0 ;
}

void Spinner::timerCallback()
{
  // prepare drawing surface
  this->targetImage = Image(Image::ARGB , GUI::SPINNER_W , GUI::SPINNER_W , true) ;
  this->spinner->setImage(this->targetImage) ;
  this->spinner->setBounds(GUI::SPINNER_RECT) ;
  Graphics mask_g(this->targetImage) ;

  // calculate offsets
  int slice_w = GUI::SPINNER_W / GUI::SPINNER_FRAMES ;
  int t_mod   = this->t        % GUI::SPINNER_FRAMES ;
  int slice   = slice_w * t_mod ;
  int frame_n = this->t ;
  this->t     = (this->t + 1)  % GUI::SPINNER_FRAMES4 ;

  // draw image
  int x , w ;
  if      (frame_n < GUI::SPINNER_FRAMES ) { x = 0 ;     w = slice ;                  } // wipe_in
  else if (frame_n < GUI::SPINNER_FRAMES2) { x = 0 ;     w = GUI::SPINNER_W ;         } // draw_full
  else if (frame_n < GUI::SPINNER_FRAMES3) { x = slice ; w = GUI::SPINNER_W - slice ; } // wipe_out
  else                                     { x = slice ; w = 0 ;                      } // draw_none
  Rectangle<int> clip_rect = Rectangle<int>(x , 0 , w , GUI::SPINNER_W) ;
  mask_g.drawImageAt(this->sourceImage.getClippedImage(clip_rect) , x , 0) ;
}


/* JUCE animation example
<-- constants
const int            GUI::SPINNER_MASK_W     = SPINNER_W * 3 ;
const int            GUI::SPINNER_MASK_X     = SPINNER_X - SPINNER_W - SPINNER_W ;
const Rectangle<int> GUI::SPINNER_MASK_BEGIN = Rectangle<int>(SPINNER_MASK_X , SPINNER_Y , SPINNER_MASK_W , SPINNER_W) ;
const Rectangle<int> GUI::SPINNER_MASK_END   = Rectangle<int>(SPINNER_X      , SPINNER_Y , SPINNER_MASK_W , SPINNER_W) ;
const int            GUI::SPINNER_MASK_DUR   = 5000 ;
constants -->
<-- constructor
  this->mask        = new DrawableImage() ;
  Image    mask_img = Image(Image::ARGB , GUI::SPINNER_MASK_W , GUI::SPINNER_W , true) ;
  Graphics mask_g(mask_img) ;

  mask_g.setColour(Colours::black) ;
  mask_g.fillRect(0                  , 0 , GUI::SPINNER_W , GUI::SPINNER_W) ;
  mask_g.fillRect(GUI::SPINNER_W * 2 , 0 , GUI::SPINNER_W , GUI::SPINNER_W) ;
  this->mask->setImage(mask_img) ;
constructor -->
<-- event
  this->mask->setBounds(GUI::SPINNER_MASK_BEGIN) ;
  this->animator.animateComponent(this->mask            , GUI::SPINNER_MASK_END , 1.0f ,
                                  GUI::SPINNER_MASK_DUR , true                  , 1.0  , 1.0) ;
event -->
*/

//[/MiscUserCode]


//==============================================================================
#if 0
/*  -- Projucer information section --

    This is where the Projucer stores the metadata that describe this GUI layout, so
    make changes in here at your peril!

BEGIN_JUCER_METADATA

<JUCER_COMPONENT documentType="Component" className="Spinner" componentName=""
                 parentClasses="public Component, private Timer" constructorParams=""
                 variableInitialisers="" snapPixels="8" snapActive="1" snapShown="1"
                 overlayOpacity="0.330" fixedSize="0" initialWidth="1" initialHeight="1">
  <BACKGROUND backgroundColour="0">
    <ROUNDRECT pos="24 24 48M 48M" cornerSize="5" fill="solid: 80000000" hasStroke="0"/>
  </BACKGROUND>
  <GENERICCOMPONENT name="spinner" id="c451f74bb46373c0" memberName="spinner" virtualName=""
                    explicitFocusOrder="0" pos="0Cc 0Cc 128 128" class="DrawableImage"
                    params=""/>
</JUCER_COMPONENT>

END_JUCER_METADATA
*/
#endif


//[EndFile] You can add extra defines here...
//[/EndFile]
