/* TASKICON.C */
/* s.metrot@cryo-interactive.com */


#include "x/Version.h"
#include "x/scolplugin.h"

#include <stdio.h>

#include "objstr.h"

#include "objects/taskicon.h"
//$LB
#include "colors.h"

int OBJTYPTASKICON;
int WM_TASKICON;

/* definition des reflexes pour les icones dans la taskbar */
#define RFLTASKICON_NB 4
#define RFLTASKICON_CLICK 0
#define RFLTASKICON_UCLICK 1
#define RFLTASKICON_DCLICK 2
#define RFLTASKICON_MOVE 3

int nicon=0;

int _SETtaskIconMenu(mmachine m)
{
	MMpull(m);
	MMpull(m);
	return MMpush(m,NIL);
}

HICON createMyIcon(short *icon)
{
  HICON Hc;
  int i;
  int a,b,c;
  short icon16[256];
  char icon24[256*3];
  char icon32[256*4];
  char mask [32];
  DEVMODE d;
  HINSTANCE hinst=(HINSTANCE)SCgetExtra("this_inst");



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\ncreateMyIcon");
#endif
//***********************************


  for (i=0;i<256;i++)
  {
	if (icon[i]==icon[0])
	{
		icon16[i]=0;
		icon32[i*4]=icon32[i*4+1]=icon32[i*4+2]=icon32[i*4+3]=0;
		icon24[i*3]=icon24[i*3+1]=icon24[i*3+2]=0;
		mask[i>>3]=mask[i>>3]|((128>>(i&7)));
	}
	else
	{
		mask[i>>3]=mask[i>>3]&(~(128>>(i&7)));
		a=(icon[i]&31)<<3;
		b=(icon[i]&0x3e0)>>2;
		c=(icon[i]&0x7c00)>>7;
		icon16[i]=(a>>3)+((b>>2)<<5)+((c>>3)<<11);
		icon32[i*4]=a;
		icon32[i*4+1]=b;
		icon32[i*4+2]=c;
		icon32[i*4+3]=0;
		icon24[i*3]=a;
		icon24[i*3+1]=b;
		icon24[i*3+2]=c;
	}
  }

  
/*  for(i=0;i<32;i++) mask[i]=0;
  for(i=0;i<16;i++)
	  for(j=0;j<16;j++)
	  {
		  k=1<<i;
		  icon16[i*16+j]=k;
	  }

*/

  d.dmSize=sizeof(DEVMODE);
  d.dmDriverExtra=0;
  i=0;
  if (EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&d)) i=d.dmBitsPerPel;
  //MMechostr(MSKDEBUG,"create Icon %dbits\n",i);
  if (i==32) Hc= CreateIcon  ( hinst,16,16,1,32,(unsigned char*)mask,(unsigned char*)icon32);
  else if (i==16) Hc= CreateIcon  ( hinst,16,16,1,16,(unsigned char*)mask,(unsigned char*)icon16);
  else Hc= CreateIcon  ( hinst,16,16,1,24,(unsigned char*)mask,(unsigned char*)icon24);


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\ncreateMyIcon end");
#endif
//***********************************

  return Hc;
}






int CRtaskIconbis(mmachine m,short* icon,int s)
{
  HICON Hc;
  NOTIFYICONDATA *icondata;
  int res;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nCRtaskIconbis ");
#endif
//***********************************

  Hc=createMyIcon(icon);
  icondata=(NOTIFYICONDATA*)malloc(sizeof(NOTIFYICONDATA));
  if (!icondata) 
  {
    MMset(m,0,NIL);
    return 0;
  }

  icondata->cbSize=sizeof(NOTIFYICONDATA); 
  icondata->hWnd=(HWND)SCgetExtra("hscol"); 
  icondata->uID=++nicon;
  icondata->uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; 
  icondata->uCallbackMessage=WM_TASKICON; 
  icondata->hIcon=Hc; 
  strncpy(icondata->szTip,MMstartstr(m,s),64); 

  res=MMmalloc(m,1,TYPEBUF);
  if (res==NIL) return MERRMEM;
  MMstore(m,res,0,(int)icondata);

  Shell_NotifyIcon(NIM_ADD,icondata);
// MMechostr(MSKDEBUG,"hicon = %d\n",Hc);
  if (MMpush (m,(res*2)+1)) return MERRMEM;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nCRtaskIconbis end");
#endif
//***********************************

  return OBJcreate(m,OBJTYPTASKICON,nicon,-1,0);
}






int _CRtaskIcon (mmachine m)
{
  int pere,s;
  short icon [256];


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_CRtaskIcon");
#endif
//***********************************

  s=MMpull(m)>>1;
  pere=MMpull(m)>>1;
  if (s==NIL || pere==NIL) 
  {
    MMset(m,0,NIL);
    return 0;
  }
  
  if (MMsizestr(m,pere)<512)
    memcpy(icon,MMstartstr(m,pere),MMsizestr(m,pere)); 
  else
    memcpy(icon,MMstartstr(m,pere),512); 



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_CRtaskIcon end");
#endif
//***********************************

  return CRtaskIconbis(m,icon,s);
}




int _CRtaskIcon2 (mmachine m)
{
  int pere,s,i,j;
  OBJBITMAP_BUFFER p;
  short icon [256];
  PtrObjVoid OB ;
  PtrObjBitmap B ;
  int offset;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_CRtaskIcon2");
#endif
//***********************************

  s=MMpull(m)>>1;
  pere=MMpull(m)>>1;
  if (s==NIL || pere==NIL) 
  {
    MMset(m,0,NIL);
    return 0;
  }

  OB = ( PtrObjVoid ) MMstart(m,pere);
  if ( OB->Type != OBJ_TYPE_BITMAP << 1 )
  {
	MMset(m,0,NIL);
    return 0;
  }
  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);
  p = (OBJBITMAP_BUFFER)B->bits;
  for(j=0;j<16;j++)
	  for(i=0;i<16;i++)
	  {
		  //$LB
		  offset = ((j*B->TailleH*B->BPL)>>4) + (((i*B->TailleW)>>4)*3);

		  icon[i+(j<<4)] = _COLOR_BGR_TO_I15 ( p[offset+2], p[offset+1], p[offset+0] );
	  }


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_CRtaskIcon2 end");
#endif
//***********************************

  return CRtaskIconbis(m,icon,s);
}





int _SETtaskIconText (mmachine m)
{
  NOTIFYICONDATA *icondata;
  int icon,s;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconText");
#endif
//***********************************
  
  s=MMpull(m)>>1;
  icon=MMget(m,0)>>1;
  if (icon==NIL || s==NIL) return 0;
  
  icondata=(NOTIFYICONDATA *)MMfetch(m,icon,0);
  strncpy(icondata->szTip,MMstartstr(m,s),64);

  icondata->uFlags=NIF_TIP; 
  Shell_NotifyIcon(NIM_MODIFY,icondata);


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconText end");
#endif
//***********************************

  return 0;
}





int _SETtaskIconImagebis (mmachine m,short* icon,int myicon)
{
  HICON Hc;
  NOTIFYICONDATA *icondata;



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImagebis");
#endif
//***********************************

  icondata=(NOTIFYICONDATA *)MMfetch(m,myicon,0);
  DestroyIcon(icondata->hIcon);

  Hc=createMyIcon(icon);

  icondata->uFlags=NIF_ICON; 
  icondata->hIcon=Hc; 

  Shell_NotifyIcon(NIM_MODIFY,icondata);



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImagebis end");
#endif
//***********************************

  return 0;
}





int _SETtaskIconImage (mmachine m)
{
  int pere,myicon;
  short icon [256];



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImage");
#endif
//***********************************

  pere=MMpull(m)>>1;
  myicon=MMget(m,0)>>1;
  if (myicon==NIL || pere==NIL) 
  {
    MMset(m,0,NIL);
    return 0;
  }

  if (MMsizestr(m,pere)<512)
    memcpy(icon,MMstartstr(m,pere),MMsizestr(m,pere)); 
  else
    memcpy(icon,MMstartstr(m,pere),512); 



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImage end");
#endif
//***********************************

  return _SETtaskIconImagebis(m,icon,myicon);
}






int _SETtaskIconImage2 (mmachine m)
{
  int pere,myicon,i,j;
  short icon [256];
  OBJBITMAP_BUFFER p;
  PtrObjVoid OB ;
  PtrObjBitmap B ;
  int offset;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImage2");
#endif
//***********************************

  pere=MMpull(m)>>1;
  myicon=MMget(m,0)>>1;
  if (myicon==NIL || pere==NIL) 
  {
    MMset(m,0,NIL);
    return 0;
  }

  OB = ( PtrObjVoid ) MMstart(m,pere);
  if ( OB->Type != OBJ_TYPE_BITMAP << 1 )
  {
	MMset(m,0,NIL);
    return 0;
  }
  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);
  p = (OBJBITMAP_BUFFER )B->bits;
  for(j=0;j<16;j++)
	  for(i=0;i<16;i++)
	  {
		//$LB
		  offset = ((j*B->TailleH*B->BPL)>>4) + (((i*B->TailleW)>>4)*3);

		  icon[i+(j<<4)] = _COLOR_BGR_TO_I15 (p[offset+2], p[offset+1], p[offset+0]);
	  }


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETtaskIconImage2 end");
#endif
//***********************************

  return _SETtaskIconImagebis(m,icon,myicon);
}






int _DStaskIcon(mmachine m)
{
  int myicon;
  NOTIFYICONDATA *icondata;



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_DStaskIcon");
#endif
//***********************************

  myicon=MMget(m,0)>>1;
  if (myicon==NIL) 
    return 0;

  icondata=(NOTIFYICONDATA *)MMfetch(m,myicon,0);
  icondata->uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; 
  Shell_NotifyIcon(NIM_DELETE,icondata);
  DestroyIcon(icondata->hIcon);

  MMset(m,0,NIL);


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_DStaskIcon end");
#endif
//***********************************

  return 0;
}





int TaskIconEventScol(mmachine m,HWND hwnd,unsigned msg,UINT wParam, LONG lParam,int *ret)
{
  int lr,reflex,k;


  
//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nTaskIconEventScol");
#endif
//***********************************


  switch (lParam)
  {
  case 512: // mouseover the icon
    reflex=RFLTASKICON_MOVE;
    break;
  case 513: // left click
    reflex=RFLTASKICON_CLICK;
    lr=0;
    break;
  case 514: // left unclick
    reflex=RFLTASKICON_UCLICK;
    lr=0;
    break;
  case 515: // left double click
    reflex=RFLTASKICON_DCLICK;
    lr=0;
    break;
  case 516: // right click
    reflex=RFLTASKICON_CLICK;
    lr=1;
    break;
  case 517: // right unclick
    reflex=RFLTASKICON_UCLICK;
    lr=1;
    break;
  case 518: // right double click
    reflex=RFLTASKICON_DCLICK;
    lr=1;
    break;
  default:
    return 0;
  }

  if (OBJbeginreflex(m,OBJTYPTASKICON,wParam,reflex))
    return 0;

  if (reflex==RFLTASKICON_MOVE)
  {
    if (k=OBJcallreflex(m,0)) return k;
  }
  else
  {
    if (MMpush(m,lr<<1)) return MERRMEM;
    if (k=OBJcallreflex(m,1)) return k;
  }


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nTaskIconEventScol end");
#endif
//***********************************

  return 0;
}






int _CBtaskIconClick (mmachine m)
{
	return OBJaddreflex(m,OBJTYPTASKICON,RFLTASKICON_CLICK);
}

int _CBtaskIconDClick (mmachine m)
{
	return OBJaddreflex(m,OBJTYPTASKICON,RFLTASKICON_DCLICK);
}

int _CBtaskIconUClick (mmachine m)
{
	return OBJaddreflex(m,OBJTYPTASKICON,RFLTASKICON_UCLICK);
}

int _CBtaskIconMove (mmachine m)
{
	return OBJaddreflex(m,OBJTYPTASKICON,RFLTASKICON_MOVE);
}

int D2TASKICON(mmachine m,int handsys,int objm)
{
	NOTIFYICONDATA *icondata;



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nD2TASKICON");
#endif
//***********************************

    icondata=(NOTIFYICONDATA *)MMfetch(m,objm>>1,0);
    icondata->uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; 
    Shell_NotifyIcon(NIM_DELETE,icondata);
    DestroyIcon(icondata->hIcon);



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nD2TASKICON end");
#endif
//***********************************

	return 0;
}






int DestroyTaskIcon(mmachine m,int handsys)
{
  int myicon;
  NOTIFYICONDATA *icondata;



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nDestroyTaskIcon");
#endif
//***********************************

  myicon=OBJfindTH(m,OBJTYPTASKICON,handsys);
  if (myicon==NIL) 
    return 0;

  icondata=(NOTIFYICONDATA *)MMfetch(m,myicon,0);
  icondata->uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; 
  Shell_NotifyIcon(NIM_DELETE,icondata);
  DestroyIcon(icondata->hIcon);



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nDestroyTaskIcon end");
#endif
//***********************************

  return 0;
}




int IniTaskIcon(mmachine m)
{


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nIniTaskIcon");
#endif
//***********************************

	OBJTYPTASKICON=OBJregister(RFLTASKICON_NB,0,D2TASKICON,"OBJTYPTASKICON");
	WM_TASKICON=OBJgetUserEvent();
	OBJdefEvent(WM_TASKICON,TaskIconEventScol);


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nIniTaskIcon end");
#endif
//***********************************

	return 0;
}
