/*********************************************************************
*                    SEGGER Microcontroller GmbH                     *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*        (c) 1996 - 2020  SEGGER Microcontroller GmbH                *
*                                                                    *
*        Internet: www.segger.com    Support:  support@segger.com    *
*                                                                    *
**********************************************************************

** emWin V6.10 - Graphical user interface for embedded applications **
emWin is protected by international copyright laws.   Knowledge of the
source code may not be used to write a similar product.  This file may
only  be used  in accordance  with  a license  and should  not be  re-
distributed in any way. We appreciate your understanding and fairness.
----------------------------------------------------------------------
File        : GUI_SimpleAnimation.c
Purpose     : Sample that demonstrates how to perform a simple
              animation in emWin.
              This sample shows the simple steps for creating an
              animation, such as creating and running it, adding
              animation items and using a delete callback routine.
              Note that the window manager is not necessary for
              animations. The WM is only necessary in this sample
              because the animation moves a window.
Requirements: WindowManager - (x)
              MemoryDevices - ( )
              AntiAliasing  - ( )
              VNC-Server    - ( )
              PNG-Library   - ( )
              TrueTypeFonts - ( )
---------------------------END-OF-HEADER------------------------------
*/

#include "DIALOG.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/

#define ANIM_PERIOD   5000

/*********************************************************************
*
*       Types
*
**********************************************************************
*/
//
// Custom struct with data necessary for the animation
//
typedef struct {
  WM_HWIN hWin;
  int xPosStart;
  int yPosStart;
  int xPosDest;
  int yPosDest;
} ANIM_DATA;

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

/*********************************************************************
*
*       _cbWindow
*/
static void _cbWindow(WM_MESSAGE * pMsg) {
  switch (pMsg->MsgId) {
  case WM_PAINT:
    GUI_SetBkColor(GUI_WHITE);
    GUI_Clear();
    break;
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

/*********************************************************************
*
*       _OnDelete
*/
static void _OnDelete(void * pVoid) {
  ANIM_DATA * pData;

  //
  // Get custom void pointer
  //
  pData = (ANIM_DATA *)pVoid;
  //
  // Do something after the animation has ended...
  //
  WM_HideWindow(pData->hWin);
}

/*********************************************************************
*
*       _AnimMoveWindow
*/
static void _AnimMoveWindow(GUI_ANIM_INFO * pInfo, void * pVoid) {
  ANIM_DATA * pData;
  int         xPos;
  int         yPos;

  pData = (ANIM_DATA *)pVoid; // Get struct pointer
  //
  // Calculate new window position with the GUI_ANIM_INFO struct
  //
  xPos = pData->xPosStart + ((pData->xPosDest - pData->xPosStart) * pInfo->Pos) / GUI_ANIM_RANGE;
  yPos = pData->yPosStart + ((pData->yPosDest - pData->yPosStart) * pInfo->Pos) / GUI_ANIM_RANGE;
  //
  // Move window to new position
  //
  WM_MoveTo(pData->hWin, xPos, yPos);
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       MainTask
*/
void MainTask(void) {
  GUI_ANIM_HANDLE hAnim;
  ANIM_DATA       Data;
  WM_HWIN         hWin;

  //
  // Enable GUI
  // And multi-buffering to avoid flickering.
  //
  GUI_Init();
  WM_MULTIBUF_Enable(1);
  WM_SetDesktopColor(GUI_BLACK);
  //
  // Create a window that will be moved using an animation
  //
  hWin = WM_CreateWindowAsChild(20, 20, 50, 50, WM_HBKWIN, WM_CF_SHOW, _cbWindow, 0);
  //
  // Fill custom struct type with animation data
  // Since an animation expects a void pointer, you could in theory use any data type
  //
  Data.hWin = hWin;                       // Handle of window to be moved
  Data.xPosStart = WM_GetWinOrgX(hWin);   // X position of where the window is located
  Data.yPosStart = WM_GetWinOrgY(hWin);   // Y position of where the window is located
  Data.yPosDest = 120;                    // X position of where the window should move to
  Data.xPosDest = 200;                    // Y position of where the window should move to
  //
  // Create animation object
  //
  //   Remark: The min time/frame here is 100 to be able to notice
  //           the colors. In a real application this value should
  //           be significantly smaller to ensure a smooth motion.
  //
  //   Slice callback routine ----------------------+
  //   Custom *void pointer -----------------+      |
  //   Minimum time per frame ----------+    |      |
  //   Duration ------------+           |    |      |
  //                        |           |    |      |
  hAnim = GUI_ANIM_Create(ANIM_PERIOD, 50, &Data, NULL);
  //
  // Add animation items
  //
  //   Animation routine to be called -----------------------------+
  //   Custom *void pointer ----------------------------+          |
  //   Method of position calculation ------+           |          |
  //   End on timeline ---------+           |           |          |
  //   Start on timeline -+     |           |           |          |
  //   Anim handle --+    |     |           |           |          |
  //                 |    |     |           |           |          |
  GUI_ANIM_AddItem(hAnim, 0, ANIM_PERIOD, ANIM_LINEAR, &Data, _AnimMoveWindow);
  //
  // Start animation
  //
  // Function to be called on animation delete --+
  //                           +-----------------+
  // Num loops -----------+    |
  // Animation ------+    |    |
  //                 |    |    |
  GUI_ANIM_StartEx(hAnim, 1, _OnDelete);
  
  while (1) {
    GUI_Delay(100);
  }
}

/*************************** End of file ****************************/

