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



//
// Modifications History
//
//$LB (23/12/2002) : objbitmap 16bits to 24bits
//



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

#include <stdio.h>

#include "objstr.h"

#include "objects/taskicon.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(OBJBITMAP_BUFFER icon)
{
  HICON Hc;
  int i24, i16, i32;
  int r, g, b;
  short icon16[256];
  char icon24[256*3];
  char icon32[256*4];
  char mask [32];
  DEVMODE d;
  HINSTANCE hinst=(HINSTANCE)SCgetExtra("this_inst");

  for (i16=0, i24=0, i32=0; i16 < 256; i16++, i24+=3, i32+=4)
  {
	if (icon[i24]==icon[0])
	{
		icon16[i16 ] = 0;
		icon24[i24 ] = icon24[i24+1 ] = icon24[i24+2 ] = 0;
		icon32[i32 ] = icon32[i32+1 ] = icon32[i32+2 ] = icon32[i32+3 ] = 0;

		//$LB TODO
		mask[i16>>3] = mask[i16>>3] | ((128>>(i16&7)));
		//mask[i16>>3] = 0;
	}
	else
	{
		//$LB TODO
		//mask[i16>>3] = mask[i16>>3] & (~(128 >>(i16&7)));
		mask[i16>>3] = 1;

		b = icon[i24  ];
		g = icon[i24+1];
		r = icon[i24+2];

		icon16[i16 ] = ((b <<7) &0x7C00) | ((g <<2) &0x03E0) | ((r >>3) &0x1F);

		icon24[i24   ] = b;
		icon24[i24+1 ] = g;
		icon24[i24+2 ] = r;

		icon32[i24   ] = b;
		icon32[i24+1 ] = g;
		icon32[i24+2 ] = r;
		icon32[i24+3 ] = 0;

	}
  }



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

  return Hc;
}







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

  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;
  return OBJcreate(m,OBJTYPTASKICON,nicon,-1,0);
}




int _CRtaskIcon (mmachine m)
{
  int pere,s;
  unsigned char icon [256*3];

  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); 

  return CRtaskIconbis(m,icon,s);
}





int _CRtaskIcon2 (mmachine m)
{
  int pere,s,i,j;
  OBJBITMAP_BUFFER p;
  unsigned char icon [256*3];
  PtrObjVoid OB ;
  PtrObjBitmap B ;


  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=B->bits;


 

  for(j=0; j < (16*3*16); j+= (16*3))
  {
	  for(i=0; i < 16*3; i+=3)
	  {

		  icon[i+j  ] = p [i+j+2];
		  icon[i+j+1] = p [i+j+1];
		  icon[i+j+2] = p [i+j  ];
	  }

  }


  return CRtaskIconbis(m,icon,s);
}





int _SETtaskIconText (mmachine m)
{
  NOTIFYICONDATA *icondata;
  int icon,s;
  
  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);

  return 0;
}





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

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

  Hc=createMyIcon(icon);

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

  Shell_NotifyIcon(NIM_MODIFY,icondata);

  return 0;
}




int _SETtaskIconImage (mmachine m)
{
  int pere,myicon;
  unsigned char icon [256*3];

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

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

  return _SETtaskIconImagebis(m,icon,myicon);
}





int _SETtaskIconImage2 (mmachine m)
{
  int pere,myicon,i,j;
  unsigned char icon [256*3];
  OBJBITMAP_BUFFER p;
  PtrObjVoid OB ;
  PtrObjBitmap B ;

  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=B->bits;

for(j=0; j < (16*3*16); j+= (16*3))
  {
	  for(i=0; i < 16*3; i+=3)
	  {

		  icon[i+j  ] = p [i+j+2];
		  icon[i+j+1] = p [i+j+1];
		  icon[i+j+2] = p [i+j  ];
	  }
  }

  return _SETtaskIconImagebis(m,icon,myicon);
}





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

  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);
  return 0;
}




int TaskIconEventScol(mmachine m,HWND hwnd,unsigned msg,UINT wParam, LONG lParam,int *ret)
{
  int lr,reflex,k;
  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;
  }
  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;

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

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

  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);

  return 0;
}

int IniTaskIcon(mmachine m)
{
	OBJTYPTASKICON=OBJregister(RFLTASKICON_NB,0,D2TASKICON,"OBJTYPTASKICON");
	WM_TASKICON=OBJgetUserEvent();
	OBJdefEvent(WM_TASKICON,TaskIconEventScol);
	return 0;
}
