/// Cursor.cpp
///
/// (c) 2006-2018 by Bastian Spiegel <bs@tkscript.de>
///     - Distributed under terms of the Lesser GNU General Public License (LGPL).
///       See COPYING and <http://www.gnu.org/licenses/licenses.html#LGPL> for further information.
///

#include <stdlib.h>

#define YAC_BIGSTRING defined
#include <yac.h>

#ifdef YAC_WIN32
#include <windows.h>
#include <ddraw.h>
#endif
#include "HAL.h"
#include "sdl_includes.h"
#include "Cursor.h"

extern YAC_Host *yac_host;
extern sUI clid_Cursor;


_Cursor::_Cursor(void) {
   sdl_cursor      = NULL;
   previous_cursor = NULL;
   data            = NULL;
   mask            = NULL;
   width           = 0;
   height          = 0;
   hotx            = 0;
   hoty            = 0;
   b_created       = 0;
}

_Cursor::~_Cursor() {
   freeCursor();
}

void _Cursor::freeCursor(void) {
   if(sdl_cursor != NULL)
   {
#if 0
      // (note) occasionally crashes.
      // (todo) why ? (maybe b/c SDL_QuitSubSystem(SDL_INIT_VIDEO) has already been called?)
      SDL_FreeCursor(sdl_cursor);
#endif
      sdl_cursor = NULL;
   }
   if(data != NULL)
   {
      delete [] data;
      data = NULL;
   }
   if(mask != NULL)
   {
      delete [] mask;
      mask = NULL;
   }
   previous_cursor = NULL;
   width     = 0;
   height    = 0;
   hotx      = 0;
   hoty      = 0;
   b_created = 0;
}

sSI _Cursor::_create(YAC_Object *_s, sSI _w, sSI _h, sSI _hotx, sSI _hoty) {
   freeCursor();

   if( (_w>0) && (_h>0) )
   {
      if( ((_w&7)==0) && ((_h&7)==0) )
      {
         if(YAC_BCHK(_s, YAC_CLID_STRING))
         {
            YAC_String *s = (YAC_String *) _s;
            if(s->length >= (sUI) (_w*_h))
            {
               data = new sU8[ (_w>>3) * _h ];
               mask = new sU8[ (_w>>3) * _h ];
               memset((void*)data, 0, (_w>>3) * _h );
               memset((void*)mask, 0, (_w>>3) * _h );
               sSI x,y;
               sU8 *str = (sU8*) s->chars;
               sU8 *d = data;
               sU8 *m = mask;
               for(y=0; y<_h; y++)
               {
                  sU8 bit = 128;
                  for(x=0; x<_w; x++)
                  {
                     //yac_host->printf("x=%i bit=%01x\n", x, bit);
                     bit = bit >> 1;
                     if(bit==0)
                     {
                        bit = 128;
                        d++;
                        m++;
                     }
                     switch(*str++)
                     {
                     case 'X':
                        *d |= bit;
                        *m |= bit;
                        break;
                     case 'x':
                        *d |= bit;
                        break;
                     case '.':
                        *m |= bit;
                        break;
                     }
                  }
               }
               width  = _w;
               height = _h;
               hotx   = _hotx;
               hoty   = _hoty;
               return 1;
            }
         }
      }
   }
   return 0;
}

sSI _Cursor::_show(void) {
   if(tks_HAL->view_flags&_HAL::VP_OPENED)
   {
      if(!b_created)
      {
         if( (data!=NULL) && (mask!=NULL) )
         {
            //yac_host->printf(" data=%p mask=%p w=%i h=%i hotx=%i hoty=%i\n", data, mask, _w, _h, _hotx, _hoty);
            sdl_cursor = SDL_CreateCursor((Uint8 *)data, (Uint8 *)mask, width, height, hotx, hoty);
            b_created = (sdl_cursor != NULL);
            delete [] data;
            data = NULL;
            delete [] mask;
            mask = NULL;
         }
      }
      if(b_created)
      {
         SDL_Cursor *prev = SDL_GetCursor();
         if(prev != sdl_cursor)
         {
            previous_cursor = prev;
         }
         SDL_SetCursor(sdl_cursor);
         return 1;
      }
   }
   return 0;
}

void _Cursor::_revert(void) {
   if(tks_HAL->view_flags&_HAL::VP_OPENED)
   {
      if(previous_cursor != NULL)
      {
         SDL_SetCursor(previous_cursor);
         previous_cursor = NULL;
      }
   }
}
  
