/** \file
 * \brief GL Scrollbars base functions.
 *
 * See Copyright Notice in "iup.h"
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "iup.h"
#include "iupcbs.h"

#include "iup_object.h"
#include "iup_register.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_layout.h"

#include "iup_glcontrols.h"
#include "iup_glscrollbars.h"
#include "iup_gldraw.h"
#include "iup_glsubcanvas.h"


enum {
  SB_NONE, 
  SB_INC_X, SB_PAGEINC_X, SB_DRAG_X, SB_PAGEDEC_X, SB_DEC_X,
  SB_INC_Y, SB_PAGEINC_Y, SB_DRAG_Y, SB_PAGEDEC_Y, SB_DEC_Y
};


int iupGLScrollbarsGetSize(Ihandle* ih)
{
  return iupAttribGetInt(ih, "SCROLLBARSIZE");
}

static int iGLScrollbarsIsInsideHandlers(Ihandle* ih, int x, int y)
{
  int has_vert_scroll = 0;
  int has_horiz_scroll = 0;
  int sb_size = iupGLScrollbarsGetSize(ih);
  int width = ih->currentwidth,
    height = ih->currentheight;
  int sb_xmin = iupAttribGetInt(ih, "XMIN");
  int sb_xmax = iupAttribGetInt(ih, "XMAX");
  int sb_ymin = iupAttribGetInt(ih, "YMIN");
  int sb_ymax = iupAttribGetInt(ih, "YMAX");
  int sb_dy = iupAttribGetInt(ih, "DY");
  int sb_dx = iupAttribGetInt(ih, "DX");

  if (sb_xmax - sb_xmin > sb_dx)  /* has horizontal scrollbar */
  {
    has_horiz_scroll = 1;
    height -= sb_size;
  }

  if (sb_ymax - sb_ymin > sb_dy)  /* has vertical scrollbar */
  {
    has_vert_scroll = 1;
    width -= sb_size;
  }

  if (has_vert_scroll)
  {
    if (x >= ih->currentwidth - sb_size && x < ih->currentwidth)
    {
      int sb_posy = iupAttribGetInt(ih, "POSY");
      int ymin = 0;
      int ymax = height - 1;
      int range = ymax - ymin - 2 * sb_size;
      int sb_range = sb_ymax - sb_ymin;
      int dy = (sb_dy * range) / sb_range;
      int posy = ((sb_posy - sb_ymin) * range) / sb_range;
      posy += ymin + sb_size;

      if (y < sb_size)
        return SB_DEC_Y;
      else if (y < posy)
        return SB_PAGEDEC_Y;
      else if (y < posy + dy)
        return SB_DRAG_Y;
      else if (y < height - sb_size)
        return SB_PAGEINC_Y;
      else if (y < height)
        return SB_INC_Y;

      return SB_NONE;
    }
  }

  if (has_horiz_scroll)
  {
    if (y >= ih->currentheight - sb_size && y < ih->currentheight)
    {
      int sb_posx = iupAttribGetInt(ih, "POSX");
      int xmin = 0;
      int xmax = width - 1;
      int sb_range = sb_xmax - sb_xmin;
      int range = xmax - xmin - 2 * sb_size;
      int dx = (sb_dx * range) / sb_range;
      int posx = ((sb_posx - sb_xmin) * range) / sb_range;
      posx += xmin + sb_size;

      if (x < sb_size)
        return SB_DEC_X;
      else if (x < posx)
        return SB_PAGEDEC_X;
      else if (x < posx + dx)
        return SB_DRAG_X;
      else if (x < width - sb_size)
        return SB_PAGEINC_X;
      else if (x < width)
        return SB_INC_X;

      return SB_NONE;
    }
  }

  return SB_NONE;
}

static void iGLScrollbarsDrawVertical(Ihandle* ih, int active, const char* fgcolor, const char* bgcolor, int pressed, 
                                      int highlight, int sb_ymin, int sb_ymax, int sb_dy, int has_horiz_scroll)
{
  int sb_size = iupGLScrollbarsGetSize(ih);
  int height = ih->currentheight;
  int xmin, xmax, ymin, ymax, posy, dy, sb_range, range;
  int sb_posy = iupAttribGetInt(ih, "POSY");
  const char *fgcolor_inc = fgcolor, 
             *fgcolor_dec = fgcolor, 
             *fgcolor_drag = fgcolor;

  if (pressed)
  {
    char* presscolor = iupAttribGetStr(ih, "SB_PRESSCOLOR");
    if (presscolor)
    {
      if (pressed == SB_INC_Y)
        fgcolor_inc = presscolor;
      else if (pressed == SB_DEC_Y)
        fgcolor_dec = presscolor;
      else if (pressed == SB_DRAG_Y)
        fgcolor_drag = presscolor;
    }
  }
  else if (highlight)
  {
    char* hlcolor = iupAttribGetStr(ih, "SB_HIGHCOLOR");
    if (hlcolor)
    {
      if (highlight == SB_INC_Y)
        fgcolor_inc = hlcolor;
      else if (highlight == SB_DEC_Y)
        fgcolor_dec = hlcolor;
      else if (highlight == SB_DRAG_Y)
        fgcolor_drag = hlcolor;
    }
  }

  if (has_horiz_scroll)
    height -= sb_size;

  xmin = ih->currentwidth - sb_size;
  xmax = ih->currentwidth - 1;
  ymin = 0;
  ymax = height - 1;
  range = ymax - ymin - 2 * sb_size;
  sb_range = sb_ymax - sb_ymin;

  dy = (sb_dy * range) / sb_range;
  posy = ((sb_posy - sb_ymin) * range) / sb_range;
  posy += ymin + sb_size;

  /* draw background */
  iupGLDrawBox(ih, xmin, xmax,
                   ymin, ymax, bgcolor, 1);

  /* draw arrows */
  iupGLDrawArrow(ih, xmin + 2, ymin + 2,           sb_size - 5, fgcolor_dec, active, IUPGL_ARROW_TOP);
  iupGLDrawArrow(ih, xmin + 2, ymax - sb_size + 3, sb_size - 5, fgcolor_inc, active, IUPGL_ARROW_BOTTOM);

  /* draw handler */
  iupGLDrawBox(ih, xmin + 2, xmax - 2, posy, posy + dy, fgcolor_drag, active);
}

static void iGLScrollbarsDrawHorizontal(Ihandle* ih, int active, const char* fgcolor, const char* bgcolor, int pressed, 
                                        int highlight, int sb_xmin, int sb_xmax, int sb_dx, int has_vert_scroll)
{
  int sb_size = iupGLScrollbarsGetSize(ih);
  int width = ih->currentwidth;
  int xmin, xmax, ymin, ymax, posx, dx, sb_range, range;
  int sb_posx = iupAttribGetInt(ih, "POSX");
  const char *fgcolor_inc = fgcolor,
    *fgcolor_dec = fgcolor,
    *fgcolor_drag = fgcolor;

  if (pressed)
  {
    char* presscolor = iupAttribGetStr(ih, "SB_PRESSCOLOR");
    if (presscolor)
    {
      if (pressed == SB_INC_X)
        fgcolor_inc = presscolor;
      else if (pressed == SB_DEC_X)
        fgcolor_dec = presscolor;
      else if (pressed == SB_DRAG_X)
        fgcolor_drag = presscolor;
    }
  }
  else if (highlight)
  {
    char* hlcolor = iupAttribGetStr(ih, "SB_HIGHCOLOR");
    if (hlcolor)
    {
      if (highlight == SB_INC_X)
        fgcolor_inc = hlcolor;
      else if (highlight == SB_DEC_X)
        fgcolor_dec = hlcolor;
      else if (highlight == SB_DRAG_X)
        fgcolor_drag = hlcolor;
    }
  }

  if (has_vert_scroll)
    width -= sb_size;

  xmin = 0;
  xmax = width - 1;
  ymin = ih->currentheight - sb_size;
  ymax = ih->currentheight - 1;
  sb_range = sb_xmax - sb_xmin;
  range = xmax - xmin - 2 * sb_size;

  dx = (sb_dx * range) / sb_range;
  posx = ((sb_posx - sb_xmin) * range) / sb_range;
  posx += xmin + sb_size;

  /* draw background */
  iupGLDrawBox(ih, xmin, xmax, ymin, ymax, bgcolor, 1);

  /* draw arrows */
  iupGLDrawArrow(ih, xmin + 2,           ymin + 2, sb_size - 5, fgcolor_dec, active, IUPGL_ARROW_LEFT);
  iupGLDrawArrow(ih, xmax - sb_size + 3, ymin + 2, sb_size - 5, fgcolor_inc, active, IUPGL_ARROW_RIGHT);

  /* draw handler */
  iupGLDrawBox(ih, posx, posx + dx, ymin + 2, ymax - 2, fgcolor_drag, active);
}

void iupGLScrollbarsDraw(Ihandle* ih, int active)
{
  int has_vert_scroll = 0;
  int has_horiz_scroll = 0;
  int sb_xmin = iupAttribGetInt(ih, "XMIN");
  int sb_xmax = iupAttribGetInt(ih, "XMAX");
  int sb_ymin = iupAttribGetInt(ih, "YMIN");
  int sb_ymax = iupAttribGetInt(ih, "YMAX");
  int sb_dx = iupAttribGetInt(ih, "DX");
  int sb_dy = iupAttribGetInt(ih, "DY");
  char* fgcolor = iupAttribGetStr(ih, "SB_FORECOLOR");
  char* bgcolor = iupAttribGetStr(ih, "SB_BACKCOLOR");
  int highlight = iupAttribGetInt(ih, "_IUPGLSB_HIGHLIGHT_HANDLER");
  int pressed = iupAttribGetInt(ih, "_IUPGLSB_PRESSED_HANDLER");

  if (sb_xmax - sb_xmin > sb_dx)  /* has horizontal scrollbar */
    has_horiz_scroll = 1;

  if (sb_ymax - sb_ymin > sb_dy)  /* has vertical scrollbar */
    has_vert_scroll = 1;

  if (has_vert_scroll)
    iGLScrollbarsDrawVertical(ih, active, fgcolor, bgcolor, pressed, highlight, sb_ymin, sb_ymax, sb_dy, has_horiz_scroll);

  if (has_horiz_scroll)
    iGLScrollbarsDrawHorizontal(ih, active, fgcolor, bgcolor, pressed, highlight, sb_xmin, sb_xmax, sb_dx, has_vert_scroll);
}

void iupGLScrollbarsChildLayoutUpdate(Ihandle *ih)
{
  if (ih->firstchild)
  {
    int sb_posx = iupAttribGetInt(ih, "POSX");
    int sb_posy = iupAttribGetInt(ih, "POSY");

    iupBaseSetPosition(ih->firstchild, ih->x - sb_posx, ih->y - sb_posy);

    if (ih->firstchild->handle)
      iupLayoutUpdate(ih->firstchild);
  }
}

static void iGLScrollbarsPressX(Ihandle* ih, int handler)
{
  int sb_xmax = iupAttribGetInt(ih, "XMAX");
  int sb_xmin = iupAttribGetInt(ih, "XMIN");
  int sb_dx = iupAttribGetInt(ih, "DX");
  int sb_posx = iupAttribGetInt(ih, "POSX");

  if (handler == SB_INC_X)
  {
    int sb_linex = sb_dx / 10;
    char* linex = iupAttribGet(ih, "LINEX");
    if (linex) iupStrToInt(linex, &sb_linex);
    sb_posx += sb_linex;
  }
  else if (handler == SB_PAGEINC_X)
    sb_posx += sb_dx;
  if (handler == SB_DEC_X)
  {
    int sb_linex = sb_dx / 10;
    char* linex = iupAttribGet(ih, "LINEX");
    if (linex) iupStrToInt(linex, &sb_linex);
    sb_posx -= sb_linex;
  }
  else if (handler == SB_PAGEDEC_X)
    sb_posx -= sb_dx;

  if (sb_posx < sb_xmin)
    sb_posx = sb_xmin;
  if (sb_posx > sb_xmax - sb_dx)
    sb_posx = sb_xmax - sb_dx;

  iupAttribSetInt(ih, "POSX", sb_posx);
}

static void iGLScrollbarsPressY(Ihandle* ih, int handler)
{
  int sb_ymax = iupAttribGetInt(ih, "YMAX");
  int sb_ymin = iupAttribGetInt(ih, "YMIN");
  int sb_dy = iupAttribGetInt(ih, "DY");
  int sb_posy = iupAttribGetInt(ih, "POSY");

  if (handler == SB_INC_Y)
  {
    int sb_liney = sb_dy / 10;
    char* liney = iupAttribGet(ih, "LINEY");
    if (liney) iupStrToInt(liney, &sb_liney);
    sb_posy += sb_liney;
  }
  else if (handler == SB_PAGEINC_Y)
    sb_posy += sb_dy;
  if (handler == SB_DEC_Y)
  {
    int sb_liney = sb_dy / 10;
    char* liney = iupAttribGet(ih, "LINEY");
    if (liney) iupStrToInt(liney, &sb_liney);
    sb_posy -= sb_liney;
  }
  else if (handler == SB_PAGEDEC_Y)
    sb_posy -= sb_dy;

  if (sb_posy < sb_ymin)
    sb_posy = sb_ymin;
  if (sb_posy > sb_ymax - sb_dy)
    sb_posy = sb_ymax - sb_dy;

  iupAttribSetInt(ih, "POSY", sb_posy);
}

static int iGLScrollbarsMove(Ihandle* ih, int diff_x, int diff_y, int start_pos, int handler)
{
  int has_vert_scroll = 0;
  int has_horiz_scroll = 0;
  int sb_xmin = iupAttribGetInt(ih, "XMIN");
  int sb_xmax = iupAttribGetInt(ih, "XMAX");
  int sb_ymin = iupAttribGetInt(ih, "YMIN");
  int sb_ymax = iupAttribGetInt(ih, "YMAX");
  int sb_dx = iupAttribGetInt(ih, "DX");
  int sb_dy = iupAttribGetInt(ih, "DY");
  int sb_size = iupGLScrollbarsGetSize(ih);
  int range, sb_range;

  if (sb_xmax - sb_xmin > sb_dx)  /* has horizontal scrollbar */
    has_horiz_scroll = 1;

  if (sb_ymax - sb_ymin > sb_dy)  /* has vertical scrollbar */
    has_vert_scroll = 1;

  if (handler == SB_DRAG_Y && has_vert_scroll)
  {
    int ymin, ymax, posy, sb_posy;
    int height = ih->currentheight;
    if (has_horiz_scroll)
      height -= sb_size;

    if (diff_y == 0)
      return 0;

    ymin = 0;
    ymax = height - 1;
    range = ymax - ymin - 2 * sb_size;
    sb_range = sb_ymax - sb_ymin;

    posy = ((start_pos - sb_ymin) * range) / sb_range;
    posy += ymin + sb_size;

    posy += diff_y;

    posy -= ymin + sb_size;
    sb_posy = (posy * sb_range) / range + sb_ymin;

    if (sb_posy < sb_ymin)
      sb_posy = sb_ymin;
    if (sb_posy > sb_ymax - sb_dy)
      sb_posy = sb_ymax - sb_dy;

    if (sb_posy != start_pos)
    {
      iupAttribSetInt(ih, "POSY", sb_posy);
      return 1;
    }
  }
  else if (handler == SB_DRAG_X && has_horiz_scroll)
  {
    int xmin, xmax, posx, sb_posx;
    int width = ih->currentwidth;
    if (has_vert_scroll)
      width -= sb_size;

    if (diff_x == 0)
      return 0;

    xmin = 0;
    xmax = width - 1;
    range = xmax - xmin - 2 * sb_size;
    sb_range = sb_xmax - sb_xmin;

    posx = ((start_pos - sb_xmin) * range) / sb_range;
    posx += xmin + sb_size;

    posx += diff_x;

    posx -= xmin + sb_size;
    sb_posx = (posx * sb_range) / range + sb_xmin;

    if (sb_posx < sb_xmin)
      sb_posx = sb_xmin;
    if (sb_posx > sb_xmax - sb_dx)
      sb_posx = sb_xmax - sb_dx;

    if (sb_posx != start_pos)
    {
      iupAttribSetInt(ih, "POSX", sb_posx);
      return 1;
    }
  }

  return 0;
}

void iupGLScrollbarsCheckPosX(Ihandle *ih)
{
  int xmin = iupAttribGetInt(ih, "XMIN");
  int xmax = iupAttribGetInt(ih, "XMAX");
  int dx = iupAttribGetInt(ih, "DX");
  int posx = iupAttribGetInt(ih, "POSX");

  if (xmax == xmin || dx >= xmax-xmin)
    iupAttribSet(ih, "POSX", "0");
  else if (posx < xmin)
    iupAttribSetInt(ih, "POSX", xmin);
  else if (posx > xmax - dx)
    iupAttribSetInt(ih, "POSX", xmax - dx);
}

void iupGLScrollbarsCheckPosY(Ihandle *ih)
{
  int ymin = iupAttribGetInt(ih, "YMIN");
  int ymax = iupAttribGetInt(ih, "YMAX");
  int dy = iupAttribGetInt(ih, "DY");
  int posy = iupAttribGetInt(ih, "POSY");

  if (ymax == ymin || dy >= ymax - ymin)
    iupAttribSet(ih, "POSX", "0");
  else if (posy < ymin)
    iupAttribSetInt(ih, "POSY", ymin);
  else if (posy > ymax - dy) 
    iupAttribSetInt(ih, "POSY", ymax - dy);
}

static int iGLScrollbarsSetPosXAttrib(Ihandle *ih, const char *value)
{
  int xmin, xmax, dx;
  int posx;

  if (!iupStrToInt(value, &posx))
    return 0;

  xmin = iupAttribGetInt(ih, "XMIN");
  xmax = iupAttribGetInt(ih, "XMAX");
  dx = iupAttribGetInt(ih, "DX");

  if (posx < xmin) posx = xmin;
  if (posx > xmax - dx) posx = xmax - dx;

  iupAttribSetInt(ih, "POSX", posx);

  iupGLScrollbarsChildLayoutUpdate(ih);
  return 0;
}

static int iGLScrollbarsSetPosYAttrib(Ihandle *ih, const char *value)
{
  int ymin, ymax, dy;
  int posy;

  if (!iupStrToInt(value, &posy))
    return 0;

  ymin = iupAttribGetInt(ih, "YMIN");
  ymax = iupAttribGetInt(ih, "YMAX");
  dy = iupAttribGetInt(ih, "DY");

  if (posy < ymin) posy = ymin;
  if (posy > ymax - dy) posy = ymax - dy;

  iupAttribSetInt(ih, "POSY", posy);

  iupGLScrollbarsChildLayoutUpdate(ih);
  return 0;
}

int iupGLScrollbarsButton(Ihandle *ih, int pressed, int x, int y)
{
  if (pressed)
  {
    int handler = iGLScrollbarsIsInsideHandlers(ih, x, y);
    iupAttribSetInt(ih, "_IUPGLSB_PRESSED_HANDLER", handler);

    if (handler == SB_DRAG_X || handler == SB_DRAG_Y)
    {
      iupAttribSetInt(ih, "_IUPGLSB_START_X", x);
      iupAttribSetInt(ih, "_IUPGLSB_START_Y", y);

      if (handler == SB_DRAG_X)
        iupAttribSetStr(ih, "_IUPGLSB_START_POS", iupAttribGet(ih, "POSX"));
      else
        iupAttribSetStr(ih, "_IUPGLSB_START_POS", iupAttribGet(ih, "POSY"));
    }

    if (handler != SB_NONE)
      return 1;
  }
  else 
  {
    int press_handler = iupAttribGetInt(ih, "_IUPGLSB_PRESSED_HANDLER");
    int handler = iGLScrollbarsIsInsideHandlers(ih, x, y);
    if (handler != SB_NONE && handler != SB_DRAG_X && handler != SB_DRAG_Y &&
        handler == press_handler)
    {
      if (handler == SB_INC_X || handler == SB_PAGEINC_X ||
          handler == SB_DEC_X || handler == SB_PAGEDEC_X)
        iGLScrollbarsPressX(ih, handler);

      if (handler == SB_INC_Y || handler == SB_PAGEINC_Y ||
          handler == SB_DEC_Y || handler == SB_PAGEDEC_Y)
        iGLScrollbarsPressY(ih, handler);

      iupGLScrollbarsChildLayoutUpdate(ih);
    }
    iupAttribSet(ih, "_IUPGLSB_PRESSED_HANDLER", NULL);

    if (handler != SB_NONE)
      return 1;
  }

  return 0;
}

int iupGLScrollbarsMotion(Ihandle *ih, int x, int y)
{
  int redraw = 0;
  int handler = iGLScrollbarsIsInsideHandlers(ih, x, y);

  /* special highlight processing for scrollbar area */
  int old_handler = iupAttribGetInt(ih, "_IUPGLSB_HIGHLIGHT_HANDLER");
  if (old_handler != handler)
  {
    redraw = 1;
    iupAttribSetInt(ih, "_IUPGLSB_HIGHLIGHT_HANDLER", handler);
  }

  handler = iupAttribGetInt(ih, "_IUPGLSB_PRESSED_HANDLER");
  if (handler == SB_DRAG_X || handler == SB_DRAG_Y)
  {
    int start_x = iupAttribGetInt(ih, "_IUPGLSB_START_X");
    int start_y = iupAttribGetInt(ih, "_IUPGLSB_START_Y");
    int start_pos = iupAttribGetInt(ih, "_IUPGLSB_START_POS");

    if (iGLScrollbarsMove(ih, x - start_x, y - start_y, start_pos, handler))
    {
      iupGLScrollbarsChildLayoutUpdate(ih);
      redraw = 1;
    }
  }

  return redraw;
}

void iupGLScrollbarsEnterWindow(Ihandle* ih, int x, int y)
{
  /* special highlight processing for scrollbar area */
  int handler = iGLScrollbarsIsInsideHandlers(ih, x, y);
  iupAttribSetInt(ih, "_IUPGLSB_HIGHLIGHT_HANDLER", handler);
}

void iupGLScrollbarsLeaveWindow(Ihandle* ih)
{
  iupAttribSet(ih, "_IUPGLSB_HIGHLIGHT_HANDLER", NULL);
  iupAttribSet(ih, "_IUPGLSB_PRESSED_HANDLER", NULL);
}

void iupGLScrollbarsRegisterAttrib(Iclass* ic)
{
  iupClassRegisterAttribute(ic, "POSX", NULL, iGLScrollbarsSetPosXAttrib, "0", NULL, IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "POSY", NULL, iGLScrollbarsSetPosYAttrib, "0", NULL, IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "XMIN", NULL, NULL, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "XMAX", NULL, NULL, IUPAF_SAMEASSYSTEM, "100", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "YMIN", NULL, NULL, IUPAF_SAMEASSYSTEM, "0", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "YMAX", NULL, NULL, IUPAF_SAMEASSYSTEM, "100", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "LINEX", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "LINEY", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "DX", NULL, NULL, "10", NULL, IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "DY", NULL, NULL, "10", NULL, IUPAF_NO_INHERIT);

  iupClassRegisterAttribute(ic, "SCROLLBARSIZE", NULL, NULL, IUPAF_SAMEASSYSTEM, "11", IUPAF_NO_INHERIT);

  /* behave as AUTOHIDE is always Yes (unused) */
  /* behave as SCROLLBAR is always Yes (unused) */

  iupClassRegisterAttribute(ic, "SB_HIGHCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "90 190 255", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "SB_FORECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "110 210 230", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "SB_PRESSCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "50 150 255", IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "SB_BACKCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "200 225 245", IUPAF_NO_INHERIT);
}
