#define XVT_INCL_NATIVE
#define STRICT

#include <colors.h>                   

#if XVT_OS == XVT_OS_WIN
#include <commdlg.h>
#endif

COLOR RGB2COLOR(unsigned char red, unsigned char green, unsigned char blue)
{
  COLOR def = MAKE_COLOR(red, green, blue);

  // Se nel colore non compare l'indice cerca di calcolarlo
  const unsigned char color_index = (unsigned char)(def >> 12);
  if (color_index <= 0x0 || color_index > 0xF)                                
  {
    const COLOR native_color[11] = { COLOR_RED,     COLOR_GREEN,  COLOR_BLUE,  COLOR_CYAN, 
                                     COLOR_MAGENTA, COLOR_YELLOW, COLOR_BLACK, COLOR_DKGRAY,
                                     COLOR_GRAY,    COLOR_LTGRAY, COLOR_WHITE };
    def &= 0x00FFFFFF;                                 
    for (int c = 0; c < 11; c++)
    {
      // Confronta solo la terna R,G,B
      if (def == (native_color[c] & 0x00FFFFFF))    
      {
        def = native_color[c];
        break;
      }  
    }
  }
  
  return def;
}

COLOR choose_color(COLOR col, WINDOW win)
{ 
  int ok = FALSE;

#if XVT_OS == XVT_OS_WIN  
  CHOOSECOLOR cc;
  memset(&cc, 0, sizeof(cc));            // Azzera struttura 

  if (win == NULL_WIN) win = TASK_WIN;   // Sceglie una finestra valida
  
  HWND hwnd = (HWND)xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW);
  HDC hdc = GetDC(hwnd);
  
  // Legge la palette di sistema 
  PALETTEENTRY* pe = NULL;
  int max_entries = 0;
  if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  {                             
    max_entries = GetDeviceCaps(hdc, SIZEPALETTE);
    pe = new PALETTEENTRY[max_entries];
    GetSystemPaletteEntries(hdc, 0, max_entries, pe);
  }
  ReleaseDC(hwnd, hdc);
  
  // Definisce i 16 colori customizzabili  
  unsigned long custom_colors[16];
  for (int c = 0; c < 16; c++)
  {
    if (pe)
    {     
      const PALETTEENTRY& e = pe[c < 8 ? c : max_entries - 16 + c];
      custom_colors[c] = RGB(e.peRed, e.peGreen, e.peBlue);
    }
    else    
    {
      const unsigned char val   = (c & 0x8) ? 255 : 127;
      const unsigned char red   = (c & 0x1) ? val : 0;
      const unsigned char green = (c & 0x2) ? val : 0;
      const unsigned char blue  = (c & 0x4) ? val : 0;
      custom_colors[c] = RGB(red, green, blue);
    }  
  }
  if (pe) 
  {
    delete pe;
    pe = NULL;
  }  
    
  cc.lStructSize  = sizeof(cc);               // Setta dimensioni
  cc.hwndOwner    = hwnd;                     // Setta finestra padre
  cc.rgbResult    = RGB(XVT_COLOR_GET_RED(c), XVT_COLOR_GET_GREEN(c), XVT_COLOR_GET_BLUE(c));
  cc.lpCustColors = custom_colors;            // Fissa colori custom
  cc.Flags        = CC_RGBINIT;               // Usa col come primo colore 
    
  ok = ChooseColor(&cc) != 0;
#endif  
  
  if (ok)
    col = RGB2COLOR(GetRValue(cc.rgbResult), GetGValue(cc.rgbResult), GetBValue(cc.rgbResult));
  else
    col = COLOR_INVALID;
  
  return col;
}