/********************************************************************
 *																	*
 *	Desktop icon handling routines									*
 *	Copyright (C) 1994, Bitgate Software and Clever Bits			*
 *																	*
 *	Finally, desktop icon handling routines!  And it wasn't as easy	*
 *	to figure out as it looks.  I had to write these from scratch!	*
 *																	*
 *	These are the routines used to handle icons on the desktop, and *
 *	handle the information exchange between icons.  Although they're*
 *	not mega-sophisticated, they're sophisticated enough to handle	*
 *	the movement and iconification of windows, as well as the		*
 *	deletion of other windows.										*
 *																	*
 ********************************************************************
 *																	*
 *	Update log:														*
 *	[3.2.94 - 26.2.94] Ken Hollis									*
 *		(icons)				- added for better looking desktop		*
 *							- fixed some size problems				*
 *		(resource)			- added more icons and an info line		*
 *							- removed info line, updated icons		*
 *		WSetup_Desktop		- added									*
 *							- added fix for monochrome users		*
 *		WDesk_Redraw		- added and fixed						*
 *							- worked on majorly						*
 *		WDesk_PortionRedraw	- added and fixed						*
 *		WSet_IconPosition	- added and fixed						*
 *		WDo_Desk			- added and fixed majorly				*
 *							- added better mouse handling routine	*
 *							- added custom drag routine				*
 *							- added custom popup menu for selections*
 *							- added popup for icon selections		*
 *							- added initial click checking			*
 *							- added checking of icon states (so you	*
 *								can't uniconify a hidden icon)		*
 *							- added mouse form changing to match icn*
 *		WIconify			- added									*
 *							- added shrink box animation			*
 *							- added mouse form changing to match icn*
 *							- fixed a bug when called				*
 *		WRemove_Icon		- added									*
 *							- added move box animation				*
 *		WFindIconWindow		- added for locating a window w/an icon *
 *		(global)			- added better redraw routines			*
 *																	*
 ********************************************************************/

#include <string.h>
#include "winlib.h"

#ifndef __DESKTOP__
#define __DESKTOP__
#endif

static char ptnull[1] = "";

TEDINFO dt_tedinfo[] = {
  {"DESK  V0.26", ptnull, ptnull, 5, 0, 0, 4352, 0, 0, 12, 1}};

int clipboardmask[] = {
  0x0000,0x0000,0x0007,0xe000,0x000f,0xf000,0x01ff,0xff80,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,0x3fff,0xfffc,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

int clipboarddata[] = {
   0x0000,0x0000,0x0007,0xe000,0x000c,0x3000,0x01f9,0x9f80,
   0x3f00,0x00fc,0x2300,0x00c4,0x2fff,0xfff4,0x2fff,0xfff4,
   0x2800,0x0014,0x2918,0x2014,0x2901,0xf414,0x2984,0x0014,
   0x2800,0x0014,0x29ff,0xff14,0x2800,0x0014,0x2800,0x0014,
   0x2800,0x0014,0x2800,0x0014,0x2800,0x0014,0x29ff,0x7f94,
   0x2931,0x4c94,0x2979,0x5c94,0x2901,0x4094,0x29ff,0x7f94,
   0x2800,0x0014,0x2fff,0xfff4,0x2000,0x0004,0x3fff,0xfffc,
   0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

int trashcanmask[] = {
  0x0000,0x0000,0x0000,0x0000,0x0007,0xe000,0x007f,0xfe00,
  0x01ff,0xff80,0x03ff,0xffc0,0x03ff,0xffc0,0x01ff,0xff80,
  0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,
  0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,
  0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,
  0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,
  0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,0x01ff,0xff80,
  0x003f,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

int trashcandata[] = {
   0x0000,0x0000,0x0000,0x0000,0x0007,0xe000,0x007e,0x7e00,
   0x01c6,0x6380,0x0200,0x0040,0x03c0,0x03c0,0x017f,0xfe80,
   0x0100,0x0080,0x0144,0x2280,0x0144,0x2280,0x0144,0x2280,
   0x0144,0x2280,0x0144,0x2280,0x0144,0x2280,0x0144,0x8a80,
   0x0144,0xda80,0x0144,0x7280,0x0144,0x2280,0x0144,0x2280,
   0x0144,0x2280,0x0144,0x2280,0x0144,0x2280,0x0144,0x2280,
   0x0144,0x2280,0x0164,0x2680,0x0106,0x6080,0x01e0,0x0780,
   0x003f,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

int dialogmask[] = {
  0x7fff,0xfff8,0x7fff,0xfff8,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x0fff,0xffff,0x0fff,0xffff
};

int dialogdata[] = {
   0x0000,0x0000,0x3fff,0xfff0,0x2080,0x0410,0x2a9f,0x355e,
   0x2499,0xb41e,0x2a9f,0x355e,0x2080,0x041e,0x3fff,0xfffe,
   0x2000,0x001e,0x2fff,0xffde,0x2800,0x005e,0x280a,0xaade,
   0x2805,0x55de,0x280a,0xaade,0x2805,0x55de,0x280a,0xaade,
   0x2805,0x55de,0x2aaa,0xaade,0x2955,0x55de,0x2aaa,0xaade,
   0x2955,0x55de,0x2aaa,0xaade,0x2955,0x55de,0x2aaa,0xaade,
   0x2955,0x55de,0x2bff,0xffde,0x2fff,0xffde,0x2000,0x001e,
   0x3fff,0xfffe,0x07ff,0xfffe,0x07ff,0xfffe,0x0000,0x0000
};

int textmask[] = {
  0x7fff,0xfff8,0x7fff,0xfff8,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x0fff,0xffff,0x0fff,0xffff
};

int textdata[] = {
   0x0000,0x0000,0x3fff,0xfff0,0x2080,0x0410,0x2abf,0x655e,
   0x248c,0x341e,0x2a8c,0x655e,0x2080,0x041e,0x3fff,0xfffe,
   0x2000,0x001e,0x2020,0x001e,0x203c,0x721e,0x2022,0x8a1e,
   0x2022,0x8a1e,0x203c,0x71de,0x2000,0x001e,0x2fff,0xffde,
   0x2990,0x4f5e,0x2993,0xcf5e,0x2810,0xcf5e,0x2993,0xcf5e,
   0x2990,0x415e,0x2fff,0xffde,0x2000,0x001e,0x2fff,0xffde,
   0x2830,0x27de,0x2993,0xe1de,0x2fff,0xffde,0x2000,0x001e,
   0x3fff,0xfffe,0x07ff,0xfffe,0x07ff,0xfffe,0x0000,0x0000
};

int timermask[] = {
  0x7fff,0xfff8,0x7fff,0xfff8,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,0x7fff,0xffff,
  0x7fff,0xffff,0x7fff,0xffff,0x0fff,0xffff,0x0fff,0xffff
};

int timerdata[] = {
   0x0000,0x0000,0x3fff,0xfff0,0x2080,0x0410,0x2abf,0x655e,
   0x248c,0x641e,0x2a8c,0x655e,0x2080,0x041e,0x3fff,0xfffe,
   0x2000,0x001e,0x207f,0xf81e,0x20c0,0x0c1e,0x2303,0x031e,
   0x2603,0x019e,0x2403,0x009e,0x2c03,0x00de,0x2803,0x005e,
   0x2803,0x005e,0x2803,0x005e,0x2803,0xf05e,0x2800,0x005e,
   0x2800,0x005e,0x2c00,0x00de,0x2400,0x009e,0x2600,0x019e,
   0x2300,0x031e,0x20c0,0x0c1e,0x207f,0xf81e,0x2000,0x001e,
   0x3fff,0xfffe,0x07ff,0xfffe,0x07ff,0xfffe,0x0000,0x0000
};

int blankicon[] = {
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};

ICONBLK dt_iconblk[] = {
  {clipboardmask, clipboarddata, "CLIPBOARD", 0x1000, 0x0000, 0x0000, 0x0014, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {trashcanmask, trashcandata, "TRASHCAN", 0x1000, 0x0000, 0x0000, 0x0014, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {blankicon, blankicon, "XXXXXXXX", 0x1058, 0x0000, 0x0000, 0x000b, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {dialogmask, dialogdata, "DIALOG X", 0x1041, 0x0006, 0x000b, 0x0014, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {textmask, textdata, "TEXT X", 0x1041, 0x0004, 0x0009, 0x0014, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008},
  {timermask, timerdata, "TIMED X", 0x1058, 0x000d, 0x0014, 0x0014, 0x0000, 0x0020, 0x0020, 0x0000, 0x001e, 0x0048, 0x0008}};

OBJECT dt_object[] = {
  /* Tree #0*/
  {  -1,   1,  23,0x0014,0x0000,0x0000, (long)(0x00001173L),   0,   0, 289, 525},
  {   2,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[0]),   0,1032,   9,1540},
  {   3,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[1]),   9,1032,   9,1540},
  {   4,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[2]), 256, 256,   9,1540},
  {   5,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[3]), 256, 257,   9,1540},
  {   6,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[4]), 256, 258,   9,1540},
  {   7,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[5]), 256, 259,   9,1540},
  {   8,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[6]), 262, 256,   9,1540},
  {   9,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[7]), 262, 257,   9,1540},
  {  10,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[8]), 262, 258,   9,1540},
  {  11,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[9]), 262, 259,   9,1540},
  {  12,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[10]), 268, 256,   9,1540},
  {  13,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[11]), 268, 257,   9,1540},
  {  14,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[12]), 268, 258,   9,1540},
  {  15,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[13]), 268, 259,   9,1540},
  {  16,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[14]), 274, 256,   9,1540},
  {  17,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[15]), 274, 257,   9,1540},
  {  18,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[16]), 274, 258,   9,1540},
  {  19,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[17]), 274, 259,   9,1540},
  {  20,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[18]), 280, 256,   9,1540},
  {  21,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[19]), 280, 257,   9,1540},
  {  22,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[20]), 280, 258,   9,1540},
  {  23,  -1,  -1,0x001f,0x0041,0x0000, (long)(&dt_iconblk[21]), 280, 259,   9,1540},
  {   0,  -1,  -1,0x0015,0x0020,0x0000, (long)(&dt_tedinfo[0]),1816,1036, 520,1536}};

OBJECT ic_object[] = {
  {  -1,   1,   3,0x0014,0x0000,0x0010, (long)(0x00021100L),   0,   0,  52,   9},
  {   2,  -1,  -1,0x001f,0x0000,0x0000, (long)(&dt_iconblk[22]), 512, 768,   9,1796},
  {   3,  -1,  -1,0x001f,0x0000,0x0000, (long)(&dt_iconblk[23]), 521, 768,   9,1796},
  {   0,  -1,  -1,0x001f,0x0020,0x0000, (long)(&dt_iconblk[24]), 530, 768,   9,1796}};

static char string1[] = "  Open/Restore       ";
static char string2[] = "  Iconify            ";
static char string3[] = "  Minimize/Maximize  ";
static char string4[] = "נננננננננננננננננננננ";
static char string5[] = "  Close window       ";
static char string6[] = "  Remove icon        ";
static char string7[] = "נננננננננננננננננננננ";
static char string8[] = "  Window settings    ";

OBJECT pp_object[] = {
  /* Tree #2*/
  {  -1,   1,   1,0x0014,0x0000,0x0000, (long)(0x00001173L),   0,   0,1045,1032},
  {   0,   2,   9,0x0014,0x0000,0x0020, (long)(0x00ff1100L), 256, 256,  21,   8},
  {   3,  -1,  -1,0x001c,0x0005,0x0000, (long)(string1),   0,   0,  21,   1},
  {   4,  -1,  -1,0x001c,0x0005,0x0000, (long)(string2),   0,   1,  21,   1},
  {   5,  -1,  -1,0x001c,0x0005,0x0000, (long)(string3),   0,   2,  21,   1},
  {   6,  -1,  -1,0x001c,0x0000,0x0008, (long)(string4),   0,   3,  21,   1},
  {   7,  -1,  -1,0x001c,0x0005,0x0000, (long)(string5),   0,   4,  21,   1},
  {   8,  -1,  -1,0x001c,0x0005,0x0000, (long)(string6),   0,   5,  21,   1},
  {   9,  -1,  -1,0x001c,0x0000,0x0008, (long)(string7),   0,   6,  21,   1},
  {   1,  -1,  -1,0x001c,0x0025,0x0000, (long)(string8),   0,   7,  21,   1}};

#define DESK     0   /* BOX in Tree DESKTOP */
#define DCLIP    1   /* ICON in Tree DESKTOP */
#define DTRASH   2   /* ICON in Tree DESKTOP */
#define IC1      3   /* ICON in Tree DESKTOP */
#define IC2      4   /* ICON in Tree DESKTOP */
#define IC3      5   /* ICON in Tree DESKTOP */
#define IC4      6   /* ICON in Tree DESKTOP */
#define IC5      7   /* ICON in Tree DESKTOP */
#define IC6      8   /* ICON in Tree DESKTOP */
#define IC7      9   /* ICON in Tree DESKTOP */
#define IC8      10  /* ICON in Tree DESKTOP */
#define IC9      11  /* ICON in Tree DESKTOP */
#define IC10     12  /* ICON in Tree DESKTOP */
#define IC11     13  /* ICON in Tree DESKTOP */
#define IC12     14  /* ICON in Tree DESKTOP */
#define IC13     15  /* ICON in Tree DESKTOP */
#define IC14     16  /* ICON in Tree DESKTOP */
#define IC15     17  /* ICON in Tree DESKTOP */
#define IC16     18  /* ICON in Tree DESKTOP */
#define IC17     19  /* ICON in Tree DESKTOP */
#define IC18     20  /* ICON in Tree DESKTOP */
#define IC19     21  /* ICON in Tree DESKTOP */
#define IC20     22  /* ICON in Tree DESKTOP */
#define DESK_ID  23  /* TEXT in Tree DESKTOP */
#define WOPICON  2   /* STRING in Tree WINPOP */
#define WMINICON 3   /* STRING in Tree WINPOP */
#define WMINMAX  4   /* STRING in Tree WINPOP */
#define WKILICON 6   /* STRING in Tree WINPOP */
#define WRMVICON 7   /* STRING in Tree WINPOP */
#define WSETWIN  9   /* STRING in Tree WINPOP */

ICONBLK	*DIALICON = { &dt_iconblk[22] };
ICONBLK	*TEXTICON = { &dt_iconblk[23] };
ICONBLK *TIMEICON = { &dt_iconblk[24] };

OBJECT *desktop = dt_object;
OBJECT *iconpopup = pp_object;
OBJECT *iconsetpopup = ic_object;

GLOBAL void WSetup_Desktop(void)
{
	register int i;

	if (DesktopInstalled) {
		RFix_ObjectPos(desktop);
		RFix_ObjectPos(iconpopup);
		RFix_ObjectPos(iconsetpopup);

		desktop[DESK].ob_x		= desk.g_x;
		desktop[DESK].ob_y		= desk.g_y;
		desktop[DESK].ob_width	= desk.g_w;
		desktop[DESK].ob_height	= desk.g_h;

		if (num_colors == 2) {
			desktop[DESK].ob_spec.obspec.fillpattern = 4;
			desktop[DESK].ob_spec.obspec.interiorcol = BLACK;
		}

		desktop[DCLIP].ob_y		= (desk.g_h - desktop[DCLIP].ob_height);
		desktop[DTRASH].ob_y	= (desk.g_h - desktop[DTRASH].ob_height);
		desktop[DESK_ID].ob_x	= (desk.g_w - desktop[DESK_ID].ob_width);
		desktop[DESK_ID].ob_y	= (desk.g_h - desktop[DESK_ID].ob_height);

		desktop[DCLIP].ob_type	= (CLIP_MOUSE << 8) + G_ICON;
		desktop[DTRASH].ob_type	= (TRASH_MOUSE << 8) + G_ICON;

		for (i = IC1; i<(IC20 + 1); i++)
			desktop[i].ob_flags = SELECTABLE | TOUCHEXIT | HIDETREE;

		form_dial(0, desktop->ob_x, desktop->ob_y, desktop->ob_width, desktop->ob_height,
					desktop->ob_x, desktop->ob_y, desktop->ob_width, desktop->ob_height);

		wind_set(0, WF_NEWDESK, desktop, 0, 0);
	}
}

GLOBAL WINDOW *WFindIconWindow(int object)
{
	WINDOW *win = WindowChain;

	while (win->next) {
		if (win->objnumber == object)
			return(win);
		win = win->next;
	}
	return((WINDOW *) 0L);
}


GLOBAL void WDesk_Redraw(void)
{
	GRECT r, d;

	if (DesktopInstalled) {
		d.g_x = desk.g_x;
		d.g_y = desk.g_y;
		d.g_w = desk.g_w;
		d.g_h = desk.g_h;

		WGrafMouse(M_OFF);
		wind_update(BEG_UPDATE);

		wind_get(0, WF_FIRSTXYWH, &r.g_x, &r.g_y, &r.g_w, &r.g_h);
		while(r.g_w || r.g_h) {
			if (rc_intersect(&d, &r))
				objc_draw(desktop, 0, 16, r.g_x, r.g_y, r.g_w, r.g_h);

			wind_get(0, WF_NEXTXYWH, &r.g_x, &r.g_y, &r.g_w, &r.g_h);
		}

		wind_update(END_UPDATE);
		WGrafMouse(M_ON);
	}
}

GLOBAL void WDesk_ForceRedrawPortion(int x, int y, int w, int h)
{
	GRECT r, d;

	if (DesktopInstalled) {
		d.g_x = x;
		d.g_y = y;
		d.g_w = w;
		d.g_h = h;

		WGrafMouse(M_OFF);
		wind_update(BEG_UPDATE);

		wind_get(0, WF_FIRSTXYWH, &r.g_x, &r.g_y, &r.g_w, &r.g_h);
		while(r.g_w || r.g_h) {
			if (rc_intersect(&d, &r))
				objc_draw(desktop, 0, 99, d.g_x, d.g_y, d.g_w, d.g_h);

			wind_get(0, WF_NEXTXYWH, &r.g_x, &r.g_y, &r.g_w, &r.g_h);
		}

		wind_update(END_UPDATE);
		WGrafMouse(M_ON);
	}
}

GLOBAL void WSet_IconPosition(int object, int x, int y)
{
	OBJECT *icon = &desktop[object];

	if (DesktopInstalled) {
		icon->ob_x = x;
		icon->ob_y = y;
	}
}

GLOBAL void WDesk_RedrawPortion(int x, int y, int w, int h)
{
	int msg[8];

	msg[0] = WM_REDRAW;
	msg[3] = 0;
	msg[4] = x;
	msg[5] = desk.g_y + y;
	msg[6] = w;
	msg[7] = h;

	appl_write(Ap_ID, 16, msg);
}

LOCAL void Restore_IP(void)
{
	if (DesktopInstalled) {
		iconpopup[WOPICON].ob_state = NORMAL;
		iconpopup[WMINICON].ob_state = NORMAL;
		iconpopup[WMINMAX].ob_state = NORMAL;
		iconpopup[WKILICON].ob_state = NORMAL;
		iconpopup[WRMVICON].ob_state = NORMAL;
		iconpopup[WSETWIN].ob_state = NORMAL;
	}
}

LOCAL void Disable_DeskIP(void)
{
	if (DesktopInstalled) {
		iconpopup[WMINICON].ob_state = DISABLED;
		iconpopup[WMINMAX].ob_state = DISABLED;
		iconpopup[WKILICON].ob_state = DISABLED;
		iconpopup[WRMVICON].ob_state = DISABLED;
		iconpopup[WSETWIN].ob_state = DISABLED;
	}
}

LOCAL void Disable_DesktopIP(void)
{
	if (DesktopInstalled) {
		iconpopup[WOPICON].ob_state = DISABLED;
		iconpopup[WMINICON].ob_state = DISABLED;
		iconpopup[WMINMAX].ob_state = DISABLED;
		iconpopup[WKILICON].ob_state = DISABLED;
		iconpopup[WRMVICON].ob_state = DISABLED;
		iconpopup[WSETWIN].ob_state = DISABLED;
	}
}

LOCAL void Disable_RegularIP(void)
{
	if (DesktopInstalled) {
		iconpopup[WMINICON].ob_state = DISABLED;
		iconpopup[WMINMAX].ob_state = DISABLED;
		iconpopup[WKILICON].ob_state = DISABLED;
		iconpopup[WSETWIN].ob_state = DISABLED;
	}
}

GLOBAL void WDo_Desk(int object, int initialclicks, int mouseforms)
{
	OBJECT *d = desktop;
	EVENT event;
	int message;

	if (DesktopInstalled) {
		if (AES_VERSION >= 0x0400) {
			event.ev_mbreturn = initialclicks;
			message = MU_BUTTON;
		}

		event.ev_mbclicks = 0x101;
		event.ev_bmask = 3;
		event.ev_mbstate = 0;

		event.ev_mflags = MU_BUTTON | MU_TIMER;
		event.ev_mtlocount = 0x0000;
		event.ev_mthicount = 0x0000;

		if (AES_VERSION < 0x0400)
			message = EvntMulti(&event);

		if (message & MU_BUTTON) {
			if (event.ev_mbreturn == 1) {
				if ((d[object].ob_flags & TOUCHEXIT) && !(d[object].ob_flags & HIDETREE)) {
					int x, y, mx, my, dummy, newstate, oldx, oldy, i;
					WINDOW *delwin;

					objc_offset(d, object, &x, &y);

					oldx = x;
					oldy = y;

					if (!mouseforms) {
						newstate = desktop[object].ob_state;
						newstate |= SELECTED;
						WObjc_Change(desktop, object, 0, newstate, 1);

						graf_mouse(FLAT_HAND, 0L);
					}

					i = WDragBoxDesk(object, desktop[object].ob_width, desktop[object].ob_height, x, y,
									desk.g_x, desk.g_y, desk.g_w, desk.g_h, BLACK, 7, 0x5555,
									&x, &y, FALSE, mouseforms);

					if (!mouseforms)
						graf_mouse(ARROW, 0L);

					if ((i!=DTRASH) && (i!=DCLIP) && (i>0) && (i!=object) && !(desktop[i].ob_flags & HIDETREE))
						WFormCustAlert(3, " Drag-and-drop ",
								"Sorry, the Drag-and-drop",
								"feature is only currently",
								"available for MultiTOS or",
								"Geneva.  WinLIB PRO does",
								"not offer this (yet)."," ","[Okay"," ");

					switch(i) {
						case DTRASH:
							switch(object) {
								case DCLIP:
									WFormCustAlert(3, " Clipboard ",
									"The Clipboard is used for the",
									"pasting of objects and icons",
									"together, or for future use.",
									"The clipboard cannot currently",
									"be emptied."," ","[Okay"," ");
									break;

								case IC1:
								case IC2:
								case IC3:
								case IC4:
								case IC5:
								case IC6:
								case IC7:
								case IC8:
								case IC9:
								case IC10:
								case IC11:
								case IC12:
								case IC13:
								case IC14:
								case IC15:
								case IC16:
								case IC17:
								case IC18:
								case IC19:
								case IC20:
									if (!(desktop[object].ob_flags & HIDETREE) && (desktop[object].ob_flags & TOUCHEXIT)) {
										if (WFormCustAlert(3, " Remove icon ",
											"Do you really wish to remove",
											"this icon?  All changes will",
											"be deleted.",
											" ",
											" ","[Okay"," ","C[ancel") == 1) {
											delwin = WFindIconWindow(object);
											WKillWindow(delwin);
											WRemove_Icon(object, TRUE);
										}
									}
									break;

								case DTRASH:
									WFormCustAlert(3, " Trashcan ",
									"The trashcan cannot be opened.",
									" ",
									" ",
									" ",
									" "," ","[Okay"," ");
									break;
							}
						break;

						case DCLIP:
							switch(object) {
								case DTRASH:
									WFormCustAlert(3, " Trashcan ",
									"Illegal copy operation.",
									" ",
									" ",
									" ",
									" "," ","[Okay"," ");
									break;

								default:
									WFormCustAlert(3, " Clipboard ",
									"Cannot open the clipboard at",
									"this time.  Development for",
									"windows with selectable icons",
									"will be worked on later.",
									" "," ","[Okay"," ");
									break;
							}
						break;
					}

					graf_mouse(ARROW, 0L);
					graf_mkstate(&mx, &my, &dummy, &dummy);

					WSet_IconPosition(object, x, y - desk.g_y);

					if (!WFindAnyOpen())
						WDesk_ForceRedrawPortion(oldx, oldy, desktop[object].ob_width, desktop[object].ob_height);
					else
						WDesk_RedrawPortion(oldx, oldy - desk.g_y, desktop[object].ob_width, desktop[object].ob_height);

					if (!mouseforms) {
						newstate &= ~SELECTED;
						WObjc_Change(desktop, object, 0, newstate, 1);
					} else
						WObjc_Change(desktop, object, 0, desktop[object].ob_state, 1);
				}

				if (object == 0) {
					int ww, hh;

					WGraf_Rubberbox(event.ev_mmox, event.ev_mmoy, BLACK, 0,
								   0x0000, &ww, &hh, TRUE);
				}
			}

			if (event.ev_mbreturn == 2) {
				int newstate;
				WINDOW *newwin;

				switch (object) {
					case DCLIP:	newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								WFormCustAlert(3, " Clipboard ",
								"Cannot open the clipboard at",
								"this time.  Development for",
								"windows with selectable icons",
								"will be worked on later.",
								" "," ","[Okay"," ");

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);
								break;

					case DTRASH:newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								WFormCustAlert(3, " Trashcan ",
								"The trashcan cannot be opened.",
								"It is used for the deletion",
								"of iconified windows, or",
								"application relative info.",
								" "," ","[Okay"," ");

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);
								break;

					default:	if (!(desktop[object].ob_flags & HIDETREE) && (desktop[object].ob_flags & TOUCHEXIT) && (newwin = WFindIconWindow(object))!=(WINDOW *) 0L)
									if (WCallIconifyDispatcher(newwin, FALSE)) {
										graf_growbox(desktop[object].ob_x, desktop[object].ob_y,
													desktop[object].ob_width, desktop[object].ob_height,
													newwin->size.g_x, newwin->size.g_y,
													newwin->size.g_w, newwin->size.g_h);
										WOpenWindow(newwin);
										WRemove_Icon(object, FALSE);

										WDesk_RedrawPortion(desktop[object].ob_x, desktop[object].ob_y, desktop[object].ob_width, desktop[object].ob_height);
									}

								break;
				}
			}

			if (event.ev_mbreturn > 2) {
				/* Do hidden stuff here... */
			}
		} else {
			if (initialclicks == 1) {
				int newstate, p;
				WINDOW *newwin;

				switch (object) {
					case 0:		break;

					case DCLIP:	newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								Disable_DeskIP();

								PMovePopupCoord(iconpopup, event.ev_mmox, event.ev_mmoy);
								p = PDoPopupAddr(iconpopup);

								switch(p) {
									case WOPICON:
										WFormCustAlert(3, " Clipboard ",
										"Cannot open the clipboard at",
										"this time.  Development for",
										"windows with selectable icons",
										"will be worked on later.",
										" "," ","[Okay"," ");
										break;
								}

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								Restore_IP();
								break;

					case DTRASH:newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								Disable_DeskIP();

								PMovePopupCoord(iconpopup, event.ev_mmox, event.ev_mmoy);
								p = PDoPopupAddr(iconpopup);

								switch(p) {
									case WOPICON:
										WFormCustAlert(3, " Trashcan ",
										"The trashcan cannot be opened.",
										"It is used for the deletion",
										"of iconified windows, or",
										"application relative info.",
										" "," ","[Okay"," ");
										break;
								}

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								Restore_IP();
								break;

					default:	if (!(desktop[object].ob_flags & HIDETREE) && (desktop[object].ob_flags & TOUCHEXIT)) {
									newstate = desktop[object].ob_state;
									newstate |= SELECTED;
									WObjc_Change(desktop, object, 0, newstate, 1);

									Disable_RegularIP();

									PMovePopupCoord(iconpopup, event.ev_mmox, event.ev_mmoy);
									p = PDoPopupAddr(iconpopup);

									switch(p) {
										case WOPICON:
											newwin = WFindIconWindow(object);
											if (WCallIconifyDispatcher(newwin, FALSE)) {
												graf_growbox(desktop[object].ob_x, desktop[object].ob_y,
														desktop[object].ob_width, desktop[object].ob_height,
														newwin->size.g_x, newwin->size.g_y,
														newwin->size.g_w, newwin->size.g_h);
												WOpenWindow(newwin);
												WRemove_Icon(object, FALSE);

												WDesk_RedrawPortion(desktop[object].ob_x, desktop[object].ob_y, desktop[object].ob_width, desktop[object].ob_height);
											}
											break;

										case WRMVICON:
											newwin = WFindIconWindow(object);
											WKillWindow(newwin);
											WRemove_Icon(object, TRUE);

											WDesk_RedrawPortion(desktop[object].ob_x, desktop[object].ob_y, desktop[object].ob_width, desktop[object].ob_height);
											break;

										default:
											break;
									}

									newstate &= ~SELECTED;
									WObjc_Change(desktop, object, 0, newstate, 1);

									Restore_IP();
								}
								break;
				}
			}

			if (initialclicks == 2) {
				int newstate;
				WINDOW *newwin;

				switch (object) {
					case DCLIP:	newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								WFormCustAlert(3, " Clipboard ",
								"Cannot open the clipboard at",
								"this time.  Development for",
								"windows with selectable icons",
								"will be worked on later.",
								" "," ","[Okay"," ");

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);
								break;

					case DTRASH:newstate = desktop[object].ob_state;
								newstate |= SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);

								WFormCustAlert(3, " Trashcan ",
								"The trashcan cannot be opened.",
								"It is used for the deletion",
								"of iconified windows, or",
								"application relative info.",
								" "," ","[Okay"," ");

								newstate &= ~SELECTED;
								WObjc_Change(desktop, object, 0, newstate, 1);
								break;

					default:	if (!(desktop[object].ob_flags & HIDETREE) && (desktop[object].ob_flags & TOUCHEXIT) && (newwin = WFindIconWindow(object))!=(WINDOW *) 0L) {
									int x, y;

									graf_growbox(desktop[object].ob_x, desktop[object].ob_y,
												desktop[object].ob_width, desktop[object].ob_height,
												newwin->size.g_x, newwin->size.g_y,
												newwin->size.g_w, newwin->size.g_h);

									WOpenWindow(newwin);
									WRemove_Icon(object, FALSE);

									WDesk_RedrawPortion(desktop[object].ob_x, desktop[object].ob_y, desktop[object].ob_width, desktop[object].ob_height);
								}
								break;
				}
			}
		}
	}
}

GLOBAL void WIconify(WINDOW *win)
{
	int freeicon, found = FALSE;

	if (DesktopInstalled && !(win->state & W_DESKTOP)) {

		freeicon = (IC1 - 1);
		do {
			freeicon++;
			if (desktop[freeicon].ob_flags & HIDETREE)
				found = TRUE;
		} while((freeicon<IC20) && !(found));

		win->objnumber = freeicon;

		if (win->state & W_DIALOG) {
			desktop[freeicon].ob_flags = SELECTABLE | TOUCHEXIT;
			desktop[freeicon].ob_spec.iconblk = DIALICON;
			desktop[freeicon].ob_x = win->size.g_x;
			desktop[freeicon].ob_y = win->size.g_y;
			desktop[freeicon].ob_type = (DIALOG_MOUSE << 8) + G_ICON;

			strncpy(desktop[freeicon].ob_spec.iconblk->ib_ptext, win->origtitle, 12);

			WCruelCloseWindow(win, TRUE);
			WObjc_Change(desktop, freeicon, 0, NORMAL, 1);
		}

		if (win->state & W_TIMER) {
			desktop[freeicon].ob_flags = SELECTABLE | TOUCHEXIT;
			desktop[freeicon].ob_spec.iconblk = TIMEICON;
			desktop[freeicon].ob_x = win->size.g_x;
			desktop[freeicon].ob_y = win->size.g_y;
			desktop[freeicon].ob_type = (TIMER_MOUSE << 8) + G_ICON;

			strncpy(desktop[freeicon].ob_spec.iconblk->ib_ptext, win->origtitle, 12);

			WCruelCloseWindow(win, TRUE);
			WObjc_Change(desktop, freeicon, 0, NORMAL, 1);
		}

		if (win->state & W_TEXT) {
			desktop[freeicon].ob_flags = SELECTABLE | TOUCHEXIT;
			desktop[freeicon].ob_spec.iconblk = TEXTICON;
			desktop[freeicon].ob_x = win->size.g_x;
			desktop[freeicon].ob_y = win->size.g_y;
			desktop[freeicon].ob_type = (TEXT_MOUSE << 8) + G_ICON;

			strncpy(desktop[freeicon].ob_spec.iconblk->ib_ptext, win->origtitle, 12);

			WCruelCloseWindow(win, TRUE);
			WObjc_Change(desktop, freeicon, 0, NORMAL, 1);
		}
	}
}

GLOBAL int WRemove_Icon(int ic, int drag)
{
	int icon, x, y;

	if (DesktopInstalled) {
		icon = ic;

		if (drag)
			graf_movebox(desktop[icon].ob_width, desktop[icon].ob_height,
						desktop[icon].ob_x, desktop[icon].ob_y,
						desktop[DTRASH].ob_x, desktop[DTRASH].ob_y);

		desktop[icon].ob_flags = SELECTABLE | TOUCHEXIT | HIDETREE;
		desktop[icon].ob_type = G_ICON;

		form_dial(0, desktop->ob_x, desktop->ob_y, desktop->ob_width, desktop->ob_height,
					desktop->ob_x, desktop->ob_y, desktop->ob_width, desktop->ob_height);

		return(TRUE);
	}

	return(FALSE);
}