void acopt_redraw(ACONTROLP ctl) {
  ACOPTDP d = (ACOPTDP) ctl->d;
  
  if (d->acheck_signature != 136) {
    return;  //-- Not Valid Signature
  }
  
  if ((d->itemn > 0) && (d->draweditemn < d->itemn)) {
    ag_ccanvas(&d->client);
    ag_canvas(&d->client, d->clientWidth, d->nextY);
    ag_rect(&d->client, 0, 0, d->clientWidth, agdp()*max(acfg()->roundsz, 4), acfg()->textbg);
    //-- Set Values
    d->scrollY     = 0;
    d->maxScrollY  = d->nextY - (ctl->h - (agdp() * max(acfg()->roundsz, 4)));
    
    if (d->maxScrollY < 0) {
      d->maxScrollY = 0;
    }
    
    //-- Draw Items
    int i;
    
    for (i = 0; i < d->itemn; i++) {
      acopt_redrawitem(ctl, i);
    }
    
    d->draweditemn = d->itemn;
  }
}
void acopt_ondraw(void * x){
  ACONTROLP   ctl= (ACONTROLP) x;
  ACOPTDP   d  = (ACOPTDP) ctl->d;
  CANVAS *    pc = &ctl->win->c;
  acopt_redraw(ctl);
  if (d->invalidDrawItem!=-1){
    d->touchedItem = d->invalidDrawItem;
    acopt_redrawitem(ctl,d->invalidDrawItem);
    d->invalidDrawItem=-1;
  }
  
  //-- Init Device Pixel Size
  int minpadding = 2;
  int agdp3 = (agdp()*minpadding);
  int agdp6 = (agdp()*(minpadding*2));
  int agdpX = agdp6;
  
  ag_draw(pc,&d->control,ctl->x,ctl->y);
  // ag_draw_ex(pc,&d->client,ctl->x+agdp3,ctl->y+1,0,d->scrollY+1,ctl->w-agdp6,ctl->h-2);
  ag_draw_ex(pc,&d->client,ctl->x+agdp(),ctl->y+1,0,d->scrollY+1,ctl->w-(agdp()*2),ctl->h-2);
  
  if (d->maxScrollY>0){
    //-- Glow
    int i;
    byte isST=(d->scrollY>0)?1:0;
    byte isSB=(d->scrollY<d->maxScrollY)?1:0;
    int add_t_y = 1;
    
    for (i=0;i<agdpX;i++){
      byte alph = 255-round((((float) (i+1))/ ((float) agdpX))*230);
      if (isST)
        ag_rectopa(pc,ctl->x,ctl->y+i+add_t_y,ctl->w,1,acfg()->textbg,alph);
      if (isSB)
        ag_rectopa(pc,ctl->x,((ctl->y+ctl->h)-(add_t_y))-(i+1),ctl->w,1,acfg()->textbg,alph);
    }
    
    //-- Scrollbar
    int newh = ctl->h - agdp6;
    float scrdif    = ((float) newh) / ((float) d->client.h);
    int  scrollbarH = round(scrdif * newh);
    int  scrollbarY = round(scrdif * d->scrollY) + agdp3;
    if (d->scrollY<0){
      scrollbarY = agdp3;
      int alp = (1.0 - (((float) abs(d->scrollY)) / (((float) ctl->h)/4))) * 255;
      if (alp<0) alp = 0;
      ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
    }
    else if (d->scrollY>d->maxScrollY){
      scrollbarY = round(scrdif * d->maxScrollY) + agdp3;
      int alp = (1.0 - (((float) abs(d->scrollY-d->maxScrollY)) / (((float) ctl->h)/4))) * 255;
      if (alp<0) alp = 0;
      ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
    }
    else{
      ag_rect(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar);
    }
  }
}
void afbox_redraw(ACONTROLP ctl){
  AFBOXDP d = (AFBOXDP) ctl->d;
  if (d->acheck_signature != 177) return; //-- Not Valid Signature
  if ((d->itemn>0)&&(d->draweditemn<d->itemn)) {
    ag_ccanvas(&d->client);
    ag_canvas(&d->client,d->clientWidth,d->nextY);
    ag_rect(&d->client,0,0,d->clientWidth,agdp()*2,acfg()->textbg);
    
    //-- Set Values
    d->scrollY     = 0;
    d->maxScrollY  = d->nextY-(ctl->h-(agdp()*2));
    if (d->maxScrollY<0) d->maxScrollY=0;
    
    //-- Draw Items
    int i;
    for (i=0;i<d->itemn;i++){
      ag_rect(&d->client,0,d->items[i]->y,d->clientWidth,d->items[i]->h,acfg()->textbg);
      afbox_redrawitem(ctl,i);
    }
    d->draweditemn=d->itemn;
  }
}
void accheck_redrawitem(ACONTROLP ctl, int index){
  ACCHECKDP d = (ACCHECKDP) ctl->d;
  if (d->acheck_signature != 133) return; //-- Not Valid Signature
  if ((index>=d->itemn)||(index<0)) return; //-- Not Valid Index
  
  ACCHECKIP p = d->items[index];
  CANVAS *  c = &d->client;
  
  //-- Cleanup Background
  ag_rect(c,0,p->y,d->clientWidth,p->h,acfg()->textbg);
  
  if (p->isTitle){
    ag_roundgrad(c,0,p->y,d->clientWidth,p->h,acfg()->titlebg,acfg()->titlebg_g,0);
    ag_textf(c,d->clientTextW+(agdp()*14),(d->clientTextX-(agdp()*14))+1,p->y+p->ty,p->title,acfg()->titlebg_g,0);
    ag_text(c,d->clientTextW+(agdp()*14),d->clientTextX-(agdp()*14),p->y+p->ty-1,p->title,acfg()->titlefg,0);
  }
  else{
    color txtcolor = acfg()->textfg;
    color graycolor= acfg()->textfg_gray;
    byte isselectcolor=0;
    if (index==d->touchedItem){
      if (!atheme_draw("img.selection.push", c,0,p->y+agdp(),d->clientWidth,p->h-(agdp()*2))){
        color pshad = ag_calpushad(acfg()->selectbg_g);
        dword hl1 = ag_calcpushlight(acfg()->selectbg,pshad);
        ag_roundgrad(c,0,p->y+agdp(),d->clientWidth,p->h-(agdp()*2),acfg()->selectbg,pshad,(agdp()*acfg()->roundsz));
        ag_roundgrad(c,0,p->y+agdp(),d->clientWidth,(p->h-(agdp()*2))/2,LOWORD(hl1),HIWORD(hl1),(agdp()*acfg()->roundsz));
      }
      
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor=1;
    }
    else if ((index==d->focusedItem)&&(d->focused)){
      if (!atheme_draw("img.selection", c,0,p->y+agdp(),d->clientWidth,p->h-(agdp()*2))){
        dword hl1 = ag_calchighlight(acfg()->selectbg,acfg()->selectbg_g);
        ag_roundgrad(c,0,p->y+agdp(),d->clientWidth,p->h-(agdp()*2),acfg()->selectbg,acfg()->selectbg_g,(agdp()*acfg()->roundsz));
        ag_roundgrad(c,0,p->y+agdp(),d->clientWidth,(p->h-(agdp()*2))/2,LOWORD(hl1),HIWORD(hl1),(agdp()*acfg()->roundsz));
      }
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor=1;
    }
    if (index<d->itemn-1){
      //-- Not Last... Add Separator
      color sepcl = ag_calculatealpha(acfg()->textbg,acfg()->textfg_gray,80);
      ag_rect(c,0,p->y+p->h-1,d->clientWidth,1,sepcl);
    }
    
    //-- Now Draw The Text
    if (isselectcolor){
      ag_textf(c,d->clientTextW,d->clientTextX,p->y+p->ty,p->title,acfg()->selectbg_g,0);
      ag_textf(c,d->clientTextW,d->clientTextX,p->y+p->dy,p->desc,acfg()->selectbg_g,0);
    }
    ag_text(c,d->clientTextW,d->clientTextX-1,p->y+p->ty-1,p->title,txtcolor,0);
    ag_text(c,d->clientTextW,d->clientTextX-1,p->y+p->dy-1,p->desc,graycolor,0);
    
    //-- Now Draw The Checkbox
    int halfdp   = ceil(((float) agdp())/2);
    int halfdp2  = halfdp*2;
    int chkbox_s = (agdp()*10);
    int chkbox_x = round((d->clientTextX/2)- ((chkbox_s+2)/2));
    int chkbox_y = p->y + round((p->h/2) - (chkbox_s/2));
    
    byte drawed = 0;
    int minpad = 3*agdp();
    int addpad = 6*agdp();
    if (p->checked){
      if (index==d->touchedItem)
        drawed=atheme_draw("img.checkbox.on.push", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      else if ((index==d->focusedItem)&&(d->focused))
        drawed=atheme_draw("img.checkbox.on.focus", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      else
        drawed=atheme_draw("img.checkbox.on", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
    }
    else{
      if (index==d->touchedItem)
        drawed=atheme_draw("img.checkbox.push", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      else if ((index==d->focusedItem)&&(d->focused))
        drawed=atheme_draw("img.checkbox.focus", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      else
        drawed=atheme_draw("img.checkbox", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
    }
    if (!drawed){
      ag_roundgrad(c,
        chkbox_x,
        chkbox_y,
        chkbox_s,
        chkbox_s,
        acfg()->controlbg_g,
        acfg()->controlbg,
        0);
      ag_roundgrad(c,
        chkbox_x+halfdp,
        chkbox_y+halfdp,
        chkbox_s-halfdp2,
        chkbox_s-halfdp2,
        acfg()->textbg,
        acfg()->textbg,
        0);
      if (p->checked){
        ag_roundgrad(c,
          chkbox_x+halfdp2,
          chkbox_y+halfdp2,
          chkbox_s-(halfdp2*2),
          chkbox_s-(halfdp2*2),
          acfg()->selectbg,
          acfg()->selectbg_g,
          0);
      }
    }
  }
}
ACONTROLP acime2(
  AWINDOWP win,
  int x, int y, int w, int h,
  byte inputMsg
) {
  //-- Initializing Button Data
  ACIMEDP d = (ACIMEDP) malloc(sizeof(ACIMED));
  memset(d, 0, sizeof(ACIMED));
  //-- Set Data
  d->inputMsg = inputMsg;
  d->onShift = 0;
  d->on123   = 0;
  d->onCTRL  = 0;
  d->pushedId = 255;
  //-- Init Canvas
  ag_canvas(&d->control, w, h);
  ag_canvas(&d->control_push, w, h);
  ag_canvas(&d->control_rest, w, h);
  //-- Drawings
  ag_roundgrad(&d->control_rest, 0, 0, w, h, acfg()->navbg, acfg()->navbg_g, 0);
  ag_rect(&d->control_rest, 0, 0, w, 1, acfg()->navbg);
  ag_draw(&d->control_push, &d->control_rest, 0, 0);
  //-- Calculate Size
  int btnW = floor(w / 10);
  d->btnH = floor(h / 5);
  //-- Draw Buttons
  int i     = 0;
  int bY    = 0;
  int w1p2  = (btnW / 2);
  int w3p2  = ((btnW * 3) / 2);
  
  for (i = 0; i < 10; i++) {
    acime2_drawbutton(d, i * btnW, bY, btnW, d->btnH, i);
  }
  
  bY += d->btnH;
  
  for (i = 0; i < 9; i++) {
    acime2_drawbutton(d, w1p2 + (i * btnW), bY, btnW, d->btnH, i + 10);
  }
  
  bY += d->btnH;
  acime2_drawbutton(d, 0, bY, w3p2, d->btnH, 19);            //-- SHIFT
  
  for (i = 0; i < 7; i++) {
    acime2_drawbutton(d, w3p2 + (i * btnW), bY, btnW, d->btnH, i + 20);
  }
  
  acime2_drawbutton(d, 8.5 * btnW, bY, w3p2, d->btnH, 27);   //-- BACKSPACE
  bY += d->btnH;
  acime2_drawbutton(d, 0,       bY, w3p2,    d->btnH, 28); //-- CHANGE 123-ABC
  acime2_drawbutton(d, w3p2,    bY, w3p2,    d->btnH, 29); //-- COMMA
  acime2_drawbutton(d, w3p2 * 2,  bY, btnW * 4,  d->btnH, 30); //-- SPACE
  acime2_drawbutton(d, 7 * btnW,  bY, w3p2,    d->btnH, 31); //-- DOT
  acime2_drawbutton(d, 8.5 * btnW, bY, w3p2,    d->btnH, 32); //-- ENTER
  bY += d->btnH;
  acime2_drawbutton(d, 0,         bY, btnW * 2,    d->btnH, 33); //-- TAB
  acime2_drawbutton(d, btnW * 2,      bY, btnW * 2,    d->btnH, 34); //-- CTRL
  acime2_drawbutton(d, 4 * btnW,    bY, w3p2,    d->btnH, 35); //-- LEFT
  acime2_drawbutton(d, 5.5 * btnW,  bY, w3p2,    d->btnH, 36); //-- UP
  acime2_drawbutton(d, 7 * btnW,    bY, w3p2,    d->btnH, 37); //-- DOWN
  acime2_drawbutton(d, 8.5 * btnW,  bY, w3p2,    d->btnH, 38); //-- RIGHT
  ag_draw(&d->control, &d->control_rest, 0, 0);
  //-- Initializing Control
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy = &acime2_ondestroy;
  ctl->oninput  = &acime2_oninput;
  ctl->ondraw   = &acime2_ondraw;
  ctl->onblur   = &acime2_onblur;
  ctl->onfocus  = NULL;
  ctl->win      = win;
  ctl->x        = x;
  ctl->y        = y;
  ctl->w        = w;
  ctl->h        = h;
  ctl->forceNS  = 0;
  ctl->d        = (void *) d;
  aw_add(win, ctl);
  return ctl;
}
void acopt_redrawitem(ACONTROLP ctl, int index) {
  ACOPTDP d = (ACOPTDP) ctl->d;
  
  if (d->acheck_signature != 136) {
    return;  //-- Not Valid Signature
  }
  
  if ((index >= d->itemn) || (index < 0)) {
    return;  //-- Not Valid Index
  }
  
  ACOPTIP p = d->items[index];
  CANVAS  * c = &d->client;
  //-- Cleanup Background
  ag_rect(c, 0, p->y, d->clientWidth, p->h, acfg()->textbg);
  
  if (p->isTitle) {
    ag_roundgrad(c, 0, p->y, d->clientWidth, p->h, acfg()->controlbg,  acfg()->controlbg_g, 0);
    ag_rect(c, 0, p->y + p->h - 1, d->clientWidth, 1, acfg()->border);
    ag_rect(c, 0, p->y + p->h - 2, d->clientWidth, 1, acfg()->controlbg);
    char ntitle[256];
    snprintf(ntitle, 256, "<b>%s</b>", p->title);
    ag_textf(c, d->clientTextW + (agdp() * 14), (d->clientTextX - (agdp() * 14)) + 1, p->y + p->ty, ntitle, acfg()->controlbg, 0);
    ag_text(c, d->clientTextW + (agdp() * 14), d->clientTextX - (agdp() * 14), p->y + p->ty - 1, ntitle, acfg()->controlfg, 0);
  }
  else {
    color txtcolor = acfg()->textfg;
    color graycolor = acfg()->textfg_gray;
    byte isselectcolor = 0;
    
    if (index == d->touchedItem) {
      if (!atheme_draw("img.selection.push", c, 0, p->y + agdp(), d->clientWidth, p->h - (agdp() * 2))) {
        color pshad = ag_calpushad(acfg()->selectbg_g);
        dword hl1 = ag_calcpushlight(acfg()->selectbg, pshad);
        ag_roundgrad(c, 0, p->y + agdp(), d->clientWidth, p->h - (agdp() * 2), acfg()->selectbg, pshad, (agdp()*acfg()->roundsz));
        ag_roundgrad(c, 0, p->y + agdp(), d->clientWidth, (p->h - (agdp() * 2)) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->roundsz));
      }
      
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor = 1;
    }
    else if ((index == d->focusedItem) && (d->focused)) {
      if (!atheme_draw("img.selection", c, 0, p->y + agdp(), d->clientWidth, p->h - (agdp() * 2))) {
        dword hl1 = ag_calchighlight(acfg()->selectbg, acfg()->selectbg_g);
        ag_roundgrad(c, 0, p->y + agdp(), d->clientWidth, p->h - (agdp() * 2), acfg()->selectbg, acfg()->selectbg_g, (agdp()*acfg()->roundsz));
        ag_roundgrad(c, 0, p->y + agdp(), d->clientWidth, (p->h - (agdp() * 2)) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->roundsz));
      }
      
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor = 1;
    }
    
    if (index < d->itemn - 1) {
      //-- Not Last... Add Separator
      color sepcl = ag_calculatealpha(acfg()->textbg, acfg()->textfg_gray, 80);
      ag_rect(c, 0, p->y + p->h - 1, d->clientWidth, 1, sepcl);
    }
    
    //-- Now Draw The Text
    if (isselectcolor) {
      ag_textf(c, d->clientTextW, d->clientTextX, p->y + p->ty, p->title, acfg()->selectbg_g, 1);
      ag_textf(c, d->clientTextW, d->clientTextX, p->y + p->dy, p->desc, acfg()->selectbg_g, 0);
    }
    
    ag_text(c, d->clientTextW, d->clientTextX - 1, p->y + p->ty - 1, p->title, txtcolor, 1);
    ag_text(c, d->clientTextW, d->clientTextX - 1, p->y + p->dy - 1, p->desc, graycolor, 0);
    //-- Now Draw The Checkbox
    int halfdp   = ceil(((float) agdp()) / 2);
    int halfdp2  = halfdp * 2;
    int optbox_s = (agdp() * 10);
    int optbox_r = floor(optbox_s / 2);
    int optbox_x = round((d->clientTextX / 2) - (optbox_s / 2));
    int optbox_y = p->y + round((p->h / 2) - (optbox_s / 2));
    byte drawed = 0;
    int minpad = 3 * agdp();
    int addpad = 6 * agdp();
    
    if (p->id == d->selectedIndexs[p->group]) {
      if (index == d->touchedItem) {
        drawed = atheme_draw("img.radio.on.push", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
      else if ((index == d->focusedItem) && (d->focused)) {
        drawed = atheme_draw("img.radio.on.focus", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
      else {
        drawed = atheme_draw("img.radio.on", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
    }
    else {
      if (index == d->touchedItem) {
        drawed = atheme_draw("img.radio.push", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
      else if ((index == d->focusedItem) && (d->focused)) {
        drawed = atheme_draw("img.radio.focus", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
      else {
        drawed = atheme_draw("img.radio", c, optbox_x - minpad, optbox_y - minpad, optbox_s + addpad, optbox_s + addpad);
      }
    }
    
    if (!drawed) {
      ag_roundgrad(c,
                   optbox_x,
                   optbox_y,
                   optbox_s,
                   optbox_s,
                   acfg()->controlbg_g,
                   acfg()->controlbg,
                   optbox_r
                  );
      ag_roundgrad(c,
                   optbox_x + halfdp,
                   optbox_y + halfdp,
                   optbox_s - halfdp2,
                   optbox_s - halfdp2,
                   acfg()->textbg,
                   acfg()->textbg,
                   optbox_r - halfdp);
                   
      if (p->id == d->selectedIndexs[p->group]) {
        ag_roundgrad(c,
                     optbox_x + halfdp2,
                     optbox_y + halfdp2,
                     optbox_s - (halfdp2 * 2),
                     optbox_s - (halfdp2 * 2),
                     acfg()->selectbg,
                     acfg()->selectbg_g,
                     optbox_r - halfdp2);
      }
    }
  }
}
ACONTROLP acopt(
  AWINDOWP win,
  int x,
  int y,
  int w,
  int h
) {
  //-- Validate Minimum Size
  if (h < agdp() * 16) {
    h = agdp() * 16;
  }
  
  if (w < agdp() * 20) {
    w = agdp() * 20;
  }
  
  //-- Initializing Text Data
  ACOPTDP d        = (ACOPTDP) malloc(sizeof(ACOPTD));
  memset(d, 0, sizeof(ACOPTD));
  //-- Set Signature
  d->acheck_signature = 136;
  //-- Initializing Canvas
  ag_canvas(&d->control, w, h);
  int minpadding = 2;
  //-- Initializing Client Size
  d->clientWidth  = w - (agdp() * minpadding);
  d->clientTextW  = d->clientWidth - (agdp() * 18); // d->clientWidth - (agdp()*18) - (agdp()*acfg()->btnroundsz*2);
  d->clientTextX  = (agdp() * 18); // + (agdp()*acfg()->btnroundsz*2);
  d->client.data = NULL;
  //-- Draw Control
  ag_draw_ex(&d->control, &win->c, 0, 0, x, y, w, h);
  ag_rect(&d->control, 0, 0, w, h, acfg()->textbg);
  //-- Set Scroll Value
  d->scrollY     = 0;
  d->maxScrollY  = 0;
  d->prevTouchY  = -50;
  d->invalidDrawItem = -1;
  //-- Set Data Values
  d->items       = NULL;
  d->itemn       = 0;
  d->touchedItem = -1;
  d->focusedItem = -1;
  d->nextY       = agdp() * minpadding;
  d->draweditemn = 0;
  int i;
  
  for (i = 0; i < ACOPT_MAX_GROUP; i++) {
    d->selectedIndexs[i] = -1;
  }
  
  d->groupCounts   = 0;
  d->groupCurrId   = -1;
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy = &acopt_ondestroy;
  ctl->oninput  = &acopt_oninput;
  ctl->ondraw   = &acopt_ondraw;
  ctl->onblur   = &acopt_onblur;
  ctl->onfocus  = &acopt_onfocus;
  ctl->win      = win;
  ctl->x        = x;
  ctl->y        = y;
  ctl->w        = w;
  ctl->h        = h;
  ctl->forceNS  = 0;
  ctl->d        = (void *) d;
  aw_add(win, ctl);
  return ctl;
}
ACONTROLP actext(
  AWINDOWP win,
  int x,
  int y,
  int w,
  int h,
  char * text,
  byte isbig
){
  //-- Validate Minimum Size
  if (h<agdp()*16) h=agdp()*16;
  if (w<agdp()*16) w=agdp()*16;
    
  //-- Initializing Client Area
  int minpadding = max(acfg()->roundsz,4);
  int cw            = w-(agdp()*(minpadding*2));
  int ch            = 0;
  if (text!=NULL)
    ch = ag_txtheight(cw,text,isbig)+(agdp()*(minpadding*2));
  else
    ch = h-(agdp()*2);
  
  //-- Initializing Text Data
  ACTEXTDP d        = (ACTEXTDP) malloc(sizeof(ACTEXTD));
  memset(d,0,sizeof(ACTEXTD));
  
  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  ag_canvas(&d->control_focused,w,h);
  ag_canvas(&d->client,cw,ch);
  
  //-- Draw Control
  ag_draw_ex(&d->control,&win->c,0,0,x,y,w,h);
  ag_roundgrad(&d->control,0,0,w,h,acfg()->border,acfg()->border_g,(agdp()*acfg()->roundsz));
  ag_roundgrad(&d->control,1,1,w-2,h-2,acfg()->textbg,acfg()->textbg,(agdp()*acfg()->roundsz)-1);
  
  //-- Draw Focused Control
  ag_draw_ex(&d->control_focused,&win->c,0,0,x,y,w,h);
  ag_roundgrad(&d->control_focused,0,0,w,h,acfg()->selectbg,acfg()->selectbg_g,(agdp()*acfg()->roundsz));
  ag_roundgrad(&d->control_focused,agdp(),agdp(),w-(agdp()*2),h-(agdp()*2),acfg()->textbg,acfg()->textbg,(agdp()*(acfg()->roundsz-1)));
  
  
  //-- Draw Client
  ag_rect(&d->client,0,0,cw,ch,acfg()->textbg);
  if (text!=NULL)
    ag_text(&d->client,cw,0,agdp()*minpadding,text,acfg()->textfg,isbig);
  
  d->isbigtxt    = isbig;
  d->targetY     = 0;
  d->focused     = 0;
  d->scrollY     = 0;
  d->appendPos   = agdp()*minpadding;
  d->forceGlowTop= 0;
  d->isFixedText = 0;
  if (text!=NULL)
    d->maxScrollY  = ch-(h-(agdp()*minpadding));
  else{
    d->maxScrollY  = 0;
    d->isFixedText = 1;
  }
  if (d->maxScrollY<0) d->maxScrollY=0;
  
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy= &actext_ondestroy;
  ctl->oninput  = &actext_oninput;
  ctl->ondraw   = &actext_ondraw;
  ctl->onblur   = actext_onblur;
  ctl->onfocus  = actext_onfocus;
  ctl->win      = win;
  ctl->x        = x;
  ctl->y        = y;
  ctl->w        = w;
  ctl->h        = h;
  ctl->forceNS  = 0;
  ctl->d        = (void *) d;
  aw_add(win,ctl);
  return ctl;
}
void actext_rebuild(
  ACONTROLP ctl,
  int x,
  int y,
  int w,
  int h,
  char * text,
  byte isbig,
  byte toBottom
){
  ACTEXTDP  d  = (ACTEXTDP) ctl->d;
  int minpadding = max(acfg()->roundsz,4);
  //-- Cleanup
  ag_ccanvas(&d->control);
  ag_ccanvas(&d->control_focused);
  ag_ccanvas(&d->client);
  memset(d,0,sizeof(ACTEXTD));
  
  //-- Rebuild
  //-- Validate Minimum Size
  if (h<agdp()*16) h=agdp()*16;
  if (w<agdp()*16) w=agdp()*16;
    
  //-- Initializing Client Area
  int cw            = w-(agdp()*(minpadding*2));
  int ch            = 0;
  if (text!=NULL)
    ch = ag_txtheight(cw,text,isbig)+(agdp()*(minpadding*2));
  else
    ch = h-(agdp()*2);

  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  ag_canvas(&d->control_focused,w,h);
  ag_canvas(&d->client,cw,ch);
  
  //-- Draw Control
  ag_draw_ex(&d->control,ctl->win->bg,0,0,x,y,w,h);
  ag_roundgrad(&d->control,0,0,w,h,acfg()->border,acfg()->border_g,(agdp()*acfg()->roundsz));
  ag_roundgrad(&d->control,1,1,w-2,h-2,acfg()->textbg,acfg()->textbg,(agdp()*acfg()->roundsz)-1);
  
  //-- Draw Focused Control
  ag_draw_ex(&d->control_focused,ctl->win->bg,0,0,x,y,w,h);
  ag_roundgrad(&d->control_focused,0,0,w,h,acfg()->selectbg,acfg()->selectbg_g,(agdp()*acfg()->roundsz));
  ag_roundgrad(&d->control_focused,agdp(),agdp(),w-(agdp()*2),h-(agdp()*2),acfg()->textbg,acfg()->textbg,(agdp()*(acfg()->roundsz-1)));
  
  //-- Draw Client
  ag_rect(&d->client,0,0,cw,ch,acfg()->textbg);
  if (text!=NULL)
    ag_text(&d->client,cw,0,agdp()*minpadding,text,acfg()->textfg,isbig);
  
  d->isbigtxt    = isbig;
  d->targetY     = 0;
  d->focused     = 0;
  d->scrollY     = 0;
  d->appendPos   = agdp()*minpadding;
  d->forceGlowTop= 0;
  d->isFixedText = 0;
  if (text!=NULL)
    d->maxScrollY  = ch-(h-(agdp()*minpadding));
  else{
    d->maxScrollY  = 0;
    d->isFixedText = 1;
  }
  if (d->maxScrollY<0) d->maxScrollY=0;
  ctl->x        = x;
  ctl->y        = y;
  ctl->w        = w;
  ctl->h        = h;
  ctl->forceNS  = 0;
  
  if (toBottom){
    d->scrollY = d->maxScrollY;
  }
  
  ctl->ondraw(ctl);
  aw_draw(ctl->win);
}
void actext_appendtxt(ACONTROLP ctl,char * txt){
  ACTEXTDP   d  = (ACTEXTDP) ctl->d;
  int ch          = ag_txtheight(d->client.w,txt,d->isbigtxt);
  int canvas_h    = d->client.h;
  
  if ((d->appendPos+ch)>=canvas_h){
    int step_up = (d->appendPos+ch) - canvas_h;
    int y; int ynew=0;
    for (y=step_up; y<canvas_h; y++){
      color * rowdest = agxy(&d->client,0,ynew++);
      color * rowsrc  = agxy(&d->client,0,y);
      memcpy(rowdest,rowsrc,sizeof(color)*d->client.w);
    }
    d->appendPos -= step_up;
  }
  
  ag_rect(&d->client,0,d->appendPos,d->client.w,ch,acfg()->textbg);
  ag_text(&d->client,
    d->client.w,
    0,d->appendPos,
    txt,
    acfg()->textfg,
    d->isbigtxt);

  d->appendPos+=ch;
  
  /*
  int minpadding = max(acfg()->roundsz,4);
  int ch        = ag_txtheight(d->client.w,txt,d->isbigtxt);
  int my        = d->client.h-(agdp()*2); // -(agdp()*(minpadding*2));
  if ((d->appendPos+ch)>=my){
    if (d->appendPos<my){
      ch-=(my-d->appendPos);
    }
    int y; int ynew=0;
    for (y=ch;y<d->client.h;y++){
      color * rowdest = agxy(&d->client,0,ynew++);
      color * rowsrc  = agxy(&d->client,0,y);
      memcpy(rowdest,rowsrc,sizeof(color)*d->client.w);
    }
    int ypos = my-ch;
    ag_rect(&d->client,0,ypos,d->client.w,ch,acfg()->textbg);
    ag_text(&d->client,
      d->client.w,
      0,ypos,
      txt,
      acfg()->textfg,
      d->isbigtxt);
    d->forceGlowTop=1;
    d->appendPos=my;
  }
  else{
    ag_text(&d->client,
      d->client.w,
      0,d->appendPos,
      txt,
      acfg()->textfg,
      d->isbigtxt);
    d->appendPos+=ch;
  }
  */
  ctl->ondraw(ctl);
  aw_draw(ctl->win);
}
void actext_ondraw(void * x){
  ACONTROLP ctl= (ACONTROLP) x;
  ACTEXTDP  d  = (ACTEXTDP) ctl->d;
  CANVAS *  pc = &ctl->win->c;
  
  //-- Init Device Pixel Size
  int minpadding = max(acfg()->roundsz,4);
  int agdp3 = (agdp()*minpadding);
  int agdp6 = (agdp()*(minpadding*2));
  int agdpX = agdp6;
  
  if ((d->focused)&&(!d->isFixedText)){
    ag_draw(pc,&d->control_focused,ctl->x,ctl->y);
    ag_draw_ex(pc,&d->client,ctl->x+agdp3,ctl->y+agdp(),0,d->scrollY+agdp(),ctl->w-agdp6,ctl->h-(agdp()*2));
  }
  else{
    ag_draw(pc,&d->control,ctl->x,ctl->y);
    ag_draw_ex(pc,&d->client,ctl->x+agdp3,ctl->y+1,0,d->scrollY+1,ctl->w-agdp6,ctl->h-2);
  }
  
  
  if ((d->maxScrollY>0)||(d->forceGlowTop)){
    //-- Glow
    int i;
    byte isST=(d->scrollY>=agdp3)?1:0;
    byte isSB=(d->scrollY<=d->maxScrollY-agdp3)?1:0;
    if (d->forceGlowTop) isST=1;

    int add_t_y = 1;
    if (d->focused)
      add_t_y = agdp();
    for (i=0;i<agdpX;i++){
      byte alph = 255-round((((float) (i+1))/ ((float) agdpX))*230);
      if (isST)
        ag_rectopa(pc,ctl->x+agdp3,ctl->y+i+add_t_y,ctl->w-agdpX,1,acfg()->textbg,alph);
      if (isSB)
        ag_rectopa(pc,ctl->x+agdp3,(ctl->y+ctl->h)-(i+1)-add_t_y,ctl->w-agdpX,1,acfg()->textbg,alph);
    }
    
    if (d->maxScrollY>0){
      //-- Scrollbar
      int newh = ctl->h - agdp6;
      float scrdif    = ((float) newh) / ((float) d->client.h);
      int  scrollbarH = round(scrdif * newh);
      int  scrollbarY = round(scrdif * d->scrollY) + agdp3;
      if (d->scrollY<0){
        scrollbarY = agdp3;
        int alp = (1.0 - (((float) abs(d->scrollY)) / (((float) ctl->h)/4))) * 255;
        if (alp<0) alp = 0;
        ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
      }
      else if (d->scrollY>d->maxScrollY){
        scrollbarY = round(scrdif * d->maxScrollY) + agdp3;
        int alp = (1.0 - (((float) abs(d->scrollY-d->maxScrollY)) / (((float) ctl->h)/4))) * 255;
        if (alp<0) alp = 0;
        ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
      }
      else{
        ag_rect(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar);
      }
    }
  }
}
void afbox_ondraw(void * x){
  ACONTROLP   ctl= (ACONTROLP) x;
  AFBOXDP   d  = (AFBOXDP) ctl->d;
  CANVAS *    pc = &ctl->win->c;
  
  afbox_redraw(ctl);
  if (d->invalidDrawItem!=-1){
    d->touchedItem = d->invalidDrawItem;
    afbox_redrawitem_ex(ctl,d->invalidDrawItem);
    d->invalidDrawItem=-1;
    d->lasttouch=alib_tick();
    if (((d->boxtype==0)&&(d->check_n==0))||(d->boxtype==2))
      afbox_reghold(ctl,&d->lasttouch);
  }
  
  //-- Init Device Pixel Size
  int minpadding = 2;
  int agdp3 = (agdp()* minpadding);
  int agdp6 = (agdp()*(minpadding*2));
  int agdpX = agdp6;
  
  
  
  //-- Realtime redraw
  int dr_top=d->scrollY;
  int dr_bottom=dr_top+ctl->h;
  int i;
  for (i=0;i<d->itemn;i++){
    AFBOXIP p = d->items[i];
    if (p->y+p->h<dr_top) continue;
    else if (p->y>dr_bottom) break;
    else if (!p->drawed){
      afbox_redrawitem_ex(ctl,i);
      p->drawed=1;
    }
  }
  
  ag_draw(pc,&d->control,ctl->x,ctl->y);
  ag_draw_ex(pc,&d->client,ctl->x+agdp(),ctl->y+1,0,d->scrollY+1,ctl->w-(agdp()*2),ctl->h-2);
  
  if (d->maxScrollY>0){
    //-- Glow
    // int i;
    byte isST=(d->scrollY>0)?1:0;
    byte isSB=(d->scrollY<d->maxScrollY)?1:0;
    int add_t_y = 1;
    for (i=0;i<agdpX;i++){
      byte alph = 255-round((((float) (i+1))/ ((float) agdpX))*230);
      if (isST)
        ag_rectopa(pc,ctl->x,ctl->y+i+add_t_y,ctl->w,1,acfg()->textbg,alph);
      if (isSB)
        ag_rectopa(pc,ctl->x,((ctl->y+ctl->h)-(add_t_y))-(i+1),ctl->w,1,acfg()->textbg,alph);
    }
    
    //-- Scrollbar
    int newh = ctl->h - agdp6;
    float scrdif    = ((float) newh) / ((float) d->client.h);
    int  scrollbarH = round(scrdif * newh);
    int  scrollbarY = round(scrdif * d->scrollY) + agdp3;
    if (d->scrollY<0){
      scrollbarY = agdp3;
      int alp = (1.0 - (((float) abs(d->scrollY)) / (((float) ctl->h)/4))) * 255;
      if (alp<0) alp = 0;
      ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
    }
    else if (d->scrollY>d->maxScrollY){
      scrollbarY = round(scrdif * d->maxScrollY) + agdp3;
      int alp = (1.0 - (((float) abs(d->scrollY-d->maxScrollY)) / (((float) ctl->h)/4))) * 255;
      if (alp<0) alp = 0;
      ag_rectopa(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar, alp);
    }
    else{
      ag_rect(pc,(ctl->w-agdp()-2)+ctl->x,scrollbarY+ctl->y,agdp(),scrollbarH,acfg()->scrollbar);
    }
  }
}
void afbox_redrawitem_ex(ACONTROLP ctl, int index){
  AFBOXDP d = (AFBOXDP) ctl->d;
  if (d->acheck_signature != 177) return; //-- Not Valid Signature
  if ((index>=d->itemn)||(index<0)) return; //-- Not Valid Index
  
  AFBOXIP p = d->items[index];
  CANVAS *  c = &d->client;
  
  //-- Cleanup Background
  ag_rect(c,0,p->y,d->clientWidth,p->h,acfg()->textbg);
  
  if (p->isTitle){
    ag_roundgrad(c,0,p->y,d->clientWidth,p->h,acfg()->titlebg,acfg()->titlebg_g,0);
    ag_textf(c,d->clientTextW+(agdp()*14),(d->clientTextX-(agdp()*14))+1,p->y+p->ty,p->title,acfg()->titlebg_g,0);
    ag_text(c,d->clientTextW+(agdp()*14),d->clientTextX-(agdp()*14),p->y+p->ty-1,p->title,acfg()->titlefg,0);
  }
  else{
    color txtcolor = acfg()->textfg;
    color graycolor= acfg()->textfg_gray;
    byte isselectcolor=0;
    if (index==d->touchedItem){
      if (!atheme_draw("img.selection.push", c,0,p->y+1,d->clientWidth,p->h-2)){
        color pshad = ag_calpushad(acfg()->selectbg_g);
        dword hl1 = ag_calcpushlight(acfg()->selectbg,pshad);
        ag_roundgrad(c,0,p->y+1,d->clientWidth,p->h-3,acfg()->selectbg,pshad,(agdp()*2));
        ag_roundgrad(c,0,p->y+1,d->clientWidth,(p->h-3)/2,LOWORD(hl1),HIWORD(hl1),(agdp()*2));
      }
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor=1;
    }
    else if ((index==d->focusedItem)&&(d->focused)){
      if (!atheme_draw("img.selection", c,0,p->y+1,d->clientWidth,p->h-2)){
        dword hl1 = ag_calchighlight(acfg()->selectbg,acfg()->selectbg_g);
        ag_roundgrad(c,0,p->y+1,d->clientWidth,p->h-3,acfg()->selectbg,acfg()->selectbg_g,(agdp()*2));
        ag_roundgrad(c,0,p->y+1,d->clientWidth,(p->h-3)/2,LOWORD(hl1),HIWORD(hl1),(agdp()*2));
      }
      graycolor = txtcolor = acfg()->selectfg;
      isselectcolor=1;
    }
    if (index<d->itemn-1){
      //-- Not Last... Add Separator
      color sepcl = ag_calculatealpha(acfg()->textbg,acfg()->textfg_gray,80);
      ag_rect(c,0,p->y+p->h-1,d->clientWidth,1,sepcl);
    }
    
    //-- Now Draw The Checkbox
    int imgS = agdp()*24;
    if (p->img!=NULL){
      apng_stretch(c,p->img,agdp(),p->y+agdp(),imgS,imgS,0,0,p->img->w,p->img->h);
    }
    
    
    int txt_h = p->th+p->dh;
    int tit_y = (p->h / 2) - (txt_h / 2);
    int des_y = tit_y+p->th;
    int des_add = 0;
    if (d->boxtype!=0){
      des_add = (agdp()*16);
    }
    
    char permstr[64];
    snprintf(permstr,64,"%s",p->d_perm);
    //-- Now Draw The Text
    if (isselectcolor){
      ag_textf(c,d->clientTextW,d->clientTextX,p->y+tit_y,p->title,acfg()->selectbg_g,1);
      ag_textf(c,d->clientTextW+des_add,d->clientTextX,p->y+des_y,p->desc,acfg()->selectbg_g,0);
      ag_textf(c,d->clientTextW+des_add,d->clientTextX-1,p->y+des_y-1,p->desc,graycolor,0);
      
      ag_textf(c,d->clientTextW+des_add,d->clientTextX,p->y+des_y,permstr,acfg()->selectbg_g,0);
      ag_textf(c,d->clientTextW+des_add,d->clientTextX-1,p->y+des_y-1,permstr,graycolor,0);
    }
    else{
      ag_text(c,d->clientTextW+des_add,d->clientTextX-1,p->y+des_y-1,p->desc,graycolor,0);
      ag_text(c,d->clientTextW+des_add,d->clientTextX-1,p->y+des_y-1,permstr,graycolor,0);
    }
    ag_textf(c,d->clientTextW,d->clientTextX-1,p->y+tit_y-1,p->title,txtcolor,1);
    
    
    
    // img
    
    //-- Now Draw The Checkbox
    int halfdp   = ceil(((float) agdp())/2);
    int halfdp2  = halfdp*2;
    int chkbox_s = (agdp()*10);
    int chkbox_x = (d->clientTextX+d->clientTextW+(agdp()*9)) - ((chkbox_s+2)/2);
    int chkbox_y = p->y + round((p->h/2) - (chkbox_s/2));
    
    byte drawed = 0;
    int minpad = 3*agdp();
    int addpad = 6*agdp();
    
    if (d->boxtype==0){
      if (p->checked){
        if (index==d->touchedItem)
          drawed=atheme_draw("img.checkbox.on.push", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
        else if ((index==d->focusedItem)&&(d->focused))
          drawed=atheme_draw("img.checkbox.on.focus", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
        else
          drawed=atheme_draw("img.checkbox.on", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      }
      else{
        if (index==d->touchedItem)
          drawed=atheme_draw("img.checkbox.push", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
        else if ((index==d->focusedItem)&&(d->focused))
          drawed=atheme_draw("img.checkbox.focus", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
        else
          drawed=atheme_draw("img.checkbox", c,chkbox_x-minpad,chkbox_y-minpad,chkbox_s+addpad,chkbox_s+addpad);
      }
      if (!drawed){
        ag_roundgrad(c,
          chkbox_x,
          chkbox_y,
          chkbox_s,
          chkbox_s,
          acfg()->controlbg_g,
          acfg()->controlbg,
          0);
        ag_roundgrad(c,
          chkbox_x+halfdp,
          chkbox_y+halfdp,
          chkbox_s-halfdp2,
          chkbox_s-halfdp2,
          acfg()->textbg,
          acfg()->textbg,
          0);
        if (p->checked){
          ag_roundgrad(c,
            chkbox_x+halfdp2,
            chkbox_y+halfdp2,
            chkbox_s-(halfdp2*2),
            chkbox_s-(halfdp2*2),
            acfg()->selectbg,
            acfg()->selectbg_g,
            0);
        }
      }
    }
  }
}