void acprog_ondraw(void * x){
  ACONTROLP ctl= (ACONTROLP) x;
  APROGDP   d  = (APROGDP) ctl->d;
  CANVAS *  pc = &ctl->win->c;
  CANVAS *  c  = &d->control;
  
  if (d->hidden){
    ag_draw_ex(pc, ctl->win->bg, ctl->x, ctl->y, ctl->x, ctl->y, ctl->w, ctl->h);
    return;
  }
  
  if (d->onwait){
    int hp2    = floor(ctl->h/2.0);
    int draw_w = floor(ctl->w / 1.618);
    int move_w = ctl->w - draw_w;
    float crps = d->waitpos;
    if (crps>1.0) crps=2.0-crps;
    int move_x = round(move_w * crps);
    ag_draw(c,&d->bg,0,0);
    if (!atheme_draw("img.prograss.fill",c,move_x,0,draw_w,ctl->h)){
      dword hl1 = ag_calchighlight(acfg()->selectbg,acfg()->selectbg_g);      
      ag_roundgrad(c,move_x,0,draw_w,ctl->h,acfg()->selectbg_g,acfg()->selectbg,hp2);
      ag_roundgrad(c,move_x+2,2,draw_w-4,ctl->h-4,acfg()->selectbg,acfg()->selectbg_g,hp2-2);
      ag_roundgrad_ex(c,move_x+3,3,draw_w-6,ceil((ctl->h-6)/2.0),LOWORD(hl1),HIWORD(hl1),hp2,2,2,0,0);
    }
  }
  else if (!d->drawed){
    int issmall = -1;
    int draw_w  = d->width_current;
    int hp2     = floor(ctl->h/2.0);
    
    if (d->width_current<ctl->h){
      issmall   = d->width_current;
      draw_w    = ctl->h;
    }
    
    ag_draw(c,&d->bg,0,0);
    if (!atheme_draw("img.prograss.fill",c,0,0,draw_w,ctl->h)){
      dword hl1 = ag_calchighlight(acfg()->selectbg,acfg()->selectbg_g);      
      ag_roundgrad(c,0,0,draw_w,ctl->h,acfg()->selectbg_g,acfg()->selectbg,hp2);
      
      ag_roundgrad(c,2,2,draw_w-4,ctl->h-4,acfg()->selectbg,acfg()->selectbg_g,hp2-2);
      ag_roundgrad_ex(c,3,3,draw_w-6,ceil((ctl->h-6)/2.0),LOWORD(hl1),HIWORD(hl1),hp2,2,2,0,0);
    }
    
    if (issmall>=0)
      ag_draw_ex(c,&d->bg,issmall,0,issmall,0,ctl->w-issmall,ctl->h);

    d->drawed=1;
  }
  
  ag_draw(pc, &d->control,  ctl->x, ctl->y);
}
ACONTROLP accb(
  AWINDOWP win,
  int x,
  int y,
  int w,
  int h,
  char * textv,
  byte checked
){
  //-- Validate Minimum Size
  if (h<agdp()*16) h=agdp()*16;
  if (w<agdp()*16) w=agdp()*16;
  
  //-- Limit Title Length  
  char title[128];
  snprintf(title,128,"%s",textv);
  
  //-- Initializing Button Data
  ACCBDP d = (ACCBDP) malloc(sizeof(ACCBD));
  memset(d,0,sizeof(ACCBD));
  
  //-- Save Touch Message & Set Stats
  d->checked   = checked;
  d->focused   = 0;
  d->pushed    = 0;
  
  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  
  //-- Draw Control Background
  ag_draw_ex(&d->control,&win->c,0,0,x,y,w,h);
  
  //-- Calculate Position & Size
  int minpad    = 5*agdp();
  d->chkS       = (agdp()*10);
  int txtW      = w - ((d->chkS+6)+(agdp()*4));
  int txtX      = (d->chkS+(agdp()*4));
  int txtH      = ag_txtheight(txtW,title,0);
  int txtY      = ((h-txtH) / 2);
  if (txtY<1) txtY = 1;
  ag_textf(&d->control,txtW,minpad+txtX,txtY,title,acfg()->textbg,0);
  ag_text(&d->control,txtW,minpad+txtX-1,txtY-1,title,acfg()->textfg,0);
  
  //-- Initializing Control
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy= &accb_ondestroy;
  ctl->oninput  = &accb_oninput;
  ctl->ondraw   = &accb_ondraw;
  ctl->onblur   = &accb_onblur;
  ctl->onfocus  = &accb_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 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 aclabel_ondraw(void * x){
  ACONTROLP   ctl= (ACONTROLP) x;
  ACLABELDP   d  = (ACLABELDP) ctl->d;
  CANVAS *    pc = &ctl->win->c;
  
  if (!d->drawed){
    ag_draw_ex(&d->control,ctl->win->bg,0,0,ctl->x,ctl->y,ctl->w,ctl->h);
    
    int h = 0;
    int y = 0;
    int x = 0;
    
    if (d->vpos!=0){
      if (d->sigleAligment==0)
        h=ag_txtheight(ctl->w,d->text,d->isbig);
      else{
        h     = ag_fontheight(d->isbig);
        int w = ag_txtwidth(d->text,d->isbig);
        
        if (d->sigleAligment==2){
          //-- Center
          x = (ctl->w/2) - (w/2);
        }
        else if (d->sigleAligment==3){
          //-- Right
          x = ctl->w - w;
        }
      }
    }
    
    if (d->vpos==1){
      y = (ctl->h / 2) - (h / 2);
    }
    else if(d->vpos==2){
      y = ctl->h - h;
    }
    
    if (d->sigleAligment==0)
      ag_text(&d->control,ctl->w,x,y,d->text,d->cl,d->isbig);
    else
      ag_texts(&d->control,ctl->w,x,y,d->text,d->cl,d->isbig);

    d->drawed=1;
  }
  ag_draw(pc, &d->control,  ctl->x, ctl->y);
}
void acime2_ondraw(void * x) {
  ACONTROLP   ctl = (ACONTROLP) x;
  ACIMEDP     d  = (ACIMEDP) ctl->d;
  CANVAS   *  pc = &ctl->win->c;
  //-- Refresh undrawed items
  int i = 0;
  
  for (i = 0; i < ACIME2_BTNCNT; i++) {
    if (d->keyD[i] == 0) {
      int y = 4;
      
      if (i < 10) {
        y = 0;
      }
      else if (i < 19) {
        y = 1;
      }
      else if (i < 28) {
        y = 2;
      }
      else if (i < 33) {
        y = 3;
      }
      
      y *= d->btnH;
      ag_draw_ex(
        &d->control,
        ((d->pushedId == i) ? &d->control_push : &d->control_rest),
        d->keyX[i],
        y,
        d->keyX[i],
        y,
        d->keyW[i],
        d->btnH);
      acime2_drawbtn(ctl, i, y);
      d->keyD[i] = 1;
    }
  }
  
  ag_draw(pc, &d->control, ctl->x, ctl->y);
}
ACONTROLP accheck(
  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
  ACCHECKDP d        = (ACCHECKDP) malloc(sizeof(ACCHECKD));
  memset(d,0,sizeof(ACCHECKD));
  
  //-- Set Signature
  d->acheck_signature = 133;
  
  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  ag_canvas(&d->control_focused,w,h);
  
  int minpadding = max(acfg()->roundsz,4);
  
  //-- Initializing Client Size
  d->clientWidth  = w - (agdp()*minpadding*2);
  d->clientTextW  = 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_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)));
  
  //-- 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;
  
  d->groupCounts   = 0;
  d->groupCurrId   = -1;
  
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy= &accheck_ondestroy;
  ctl->oninput  = &accheck_oninput;
  ctl->ondraw   = &accheck_ondraw;
  ctl->onblur   = &accheck_onblur;
  ctl->onfocus  = &accheck_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 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_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);
      }
    }
  }
}
ACONTROLP acprog(
  AWINDOWP win,
  int x,
  int y,
  int w,
  int h,
  float value
){
  //-- Validate Minimum Size
  if (h<agdp()*5)  h=agdp()*5;
  if (w<agdp()*10) w=agdp()*10;
  
  //-- Initializing Button Data
  APROGDP d = (APROGDP) malloc(sizeof(APROGD));
  memset(d,0,sizeof(APROGD));
  
  //-- Save Touch Message & Set Stats
  d->value        = value;
  d->drawed       = 0;
  d->width_current= ceil(value * w);
  d->hidden       = 0;
  d->onwait       = 0;
  d->waitpos      = 0.0;
  d->wait_thread  = 0;
  
  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  ag_canvas(&d->bg,w,h);
  
  //-- Draw Background
  CANVAS * c = &d->bg;
  int hp2 = floor(h/2.0);
  ag_draw_ex(c,win->bg,0,0,x,y,w,h);
  if (!atheme_draw("img.progress",c,0,0,w,h)){
    dword hl1 = ag_calchighlight(acfg()->controlbg,acfg()->controlbg_g);
    ag_roundgrad(c,0,0,w,h,acfg()->border,acfg()->border_g,hp2);
    ag_roundgrad(c,1,1,w-2,h-2,
      ag_calculatealpha(acfg()->controlbg,  0xffff,180),
      ag_calculatealpha(acfg()->controlbg_g,0xffff,160),
      hp2-1);
    ag_roundgrad(c,2,2,w-4,h-4,acfg()->controlbg,acfg()->controlbg_g,hp2-2);
    ag_roundgrad_ex(c,2,2,w-4,ceil((h-4)/2.0),LOWORD(hl1),HIWORD(hl1),hp2-2,2,2,0,0);
  }
  
  //-- Initializing Control
  ACONTROLP ctl  = malloc(sizeof(ACONTROL));
  ctl->ondestroy= &acprog_ondestroy;
  ctl->oninput  = &acprog_oninput;
  ctl->ondraw   = &acprog_ondraw;
  ctl->onblur   = &acprog_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;
}
ACONTROLP imgbtn_reinit(
  AWINDOWP win,
  ACONTROLP ctl,
  int x,
  int y,
  int w,
  int h,
  PNGCANVAS * img,
  char * text,
  byte isflat,
  byte touchmsg
) {
  if ((ctl != NULL) && (x == 0) && (y == 0) && (h == 0) && (w == 0)) {
    x = ctl->x;
    y = ctl->y;
    w = ctl->w;
    h = ctl->h;
  }
  
  int txtw = 0;
  int txth = 0;
  int txtx = 0;
  int txty = 0;
  
  if (w < agdp() * 20) {
    w = agdp() * 20;
  }
  
  if (h < agdp() * 20) {
    h = agdp() * 20;
  }
  
  if (text != NULL) {
    //-- Initializing Text Metrics
    if ((isflat == 3) || (isflat == 4)) {
      txtw = ag_txtwidth(text, 0);
      txth = ag_fontheight(0);
      
      if (w < ((agdp() * 22) + txtw)) {
        w = ((agdp() * 22) + txtw);
      }
      
      txtx = round(w / 2) - round(((agdp() * 20) + txtw) / 2);
      txty = round(h / 2) - round(txth / 2);
    }
    else {
      txtw = ag_txtwidth(text, 0);
      txth = ag_fontheight(0);
      
      if (h < ((agdp() * 20) + txth)) {
        h = ((agdp() * 20) + txth);
      }
      
      txtx = round(w / 2) - round(txtw / 2);
      txty = (agdp() * 16);
    }
  }
  
  int imgS = agdp() * 16;
  int imgX = round(w / 2) - round(imgS / 2);
  int imgY = 0; // agdp()*2;
  int contentH = (agdp() * 16) +  txth;
  int contentY = (h / 2) - (contentH / 2);
  
  if ((isflat == 3) || (isflat == 4)) {
    imgY = round(h / 2) - round(imgS / 2);
    imgX = txtx + (agdp() * 2);
    txtx += agdp() * 20;
  }
  else {
    imgY += contentY;
    txty += contentY;
  }
  
  if (isflat == 3) {
    isflat = 0;
  }
  
  //-- Initializing Button Data
  IMGBTNDP d = NULL;
  
  if (ctl != NULL) {
    d = ctl->d;
    win = ctl->win;
  }
  else {
    d = (IMGBTNDP) malloc(sizeof(IMGBTND));
    memset(d, 0, sizeof(IMGBTND));
    //-- Save Touch Message & Set Stats
    d->focused   = 0;
    d->pushed    = 0;
    //-- Initializing Canvas
    ag_canvas(&d->control, w, h);
    ag_canvas(&d->control_pushed, w, h);
    ag_canvas(&d->control_focused, w, h);
  }
  
  d->touchmsg  = touchmsg;
  //-- Draw Rest Control
  dword hl1 = ag_calchighlight(acfg()->controlbg, acfg()->controlbg_g);
  ag_draw_ex(&d->control, win->bg, 0, 0, x, y, w, h);
  
  if (!isflat) {
    if (!atheme_draw("img.button", &d->control, 0, 0, w, h)) {
      ag_roundgrad(&d->control, 0, 0, w, h, acfg()->border, acfg()->border_g, (agdp()*acfg()->btnroundsz));
      ag_roundgrad(&d->control, 1, 1, w - 2, h - 2,
                   ag_calculatealpha(acfg()->controlbg, acfg()->winbg, 180),
                   ag_calculatealpha(acfg()->controlbg_g, acfg()->winbg, 160),
                   (agdp()*acfg()->btnroundsz) - 1
                  );
      ag_roundgrad(&d->control, 2, 2, w - 4, h - 4, acfg()->controlbg, acfg()->controlbg_g, (agdp()*acfg()->btnroundsz) - 2);
      ag_roundgrad_ex(&d->control, 2, 2, w - 4, (h - 4) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->btnroundsz) - 2, 1, 1, 0, 0);
    }
  }
  
  ag_textf(&d->control, txtw, txtx + 1, txty + 1, text, acfg()->controlbg, 0);
  ag_text(&d->control, txtw, txtx, txty, text, acfg()->controlfg, 0);
  color pshad = ag_calpushad(acfg()->selectbg_g);
  ag_draw_ex(&d->control_pushed, win->bg, 0, 0, x, y, w, h);
  int wadd = (isflat == 2) ? 2 : 0;
  int wdel = wadd * 2;
  
  //-- Draw Pushed Control
  if (!isflat) {
    hl1 = ag_calcpushlight(acfg()->selectbg, pshad);
    
    if (!atheme_draw("img.button.push", &d->control_pushed, 0, 0, w, h)) {
      ag_roundgrad(&d->control_pushed, 0, 0, w, h, acfg()->border, acfg()->border_g, (agdp()*acfg()->btnroundsz));
      //ag_roundgrad(&d->control_pushed,1,1,w-2,h-2,acfg()->controlbg,acfg()->controlbg_g,(agdp()*acfg()->btnroundsz)-1);
      ag_roundgrad(&d->control_pushed, 1, 1, w - 2, h - 2, acfg()->selectbg, pshad, (agdp()*acfg()->btnroundsz) - 1);
      ag_roundgrad_ex(&d->control_pushed, 1, 1, w - 2, (h - 2) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->btnroundsz) - 1, 1, 1, 0, 0);
    }
    
    ag_textf(&d->control_pushed, txtw, txtx + 1, txty + 1, text, acfg()->selectbg_g, 0);
    ag_text(&d->control_pushed, txtw, txtx, txty, text, acfg()->selectfg, 0);
  }
  else {
    hl1 = ag_calchighlight(acfg()->controlbg, acfg()->controlbg_g);
    
    if (!atheme_draw("img.button", &d->control_pushed, 0, 0, w, h)) {
      ag_roundgrad(&d->control_pushed, wadd, wadd, w - wdel, h - wdel, acfg()->border, acfg()->border_g, (agdp()*acfg()->btnroundsz));
      /*ag_roundgrad(&d->control_pushed,wadd+1,wadd+1,w-(2+wdel),h-(2+wdel),
        ag_calculatealpha(acfg()->controlbg,acfg()->winbg,180),
        ag_calculatealpha(acfg()->controlbg_g,acfg()->winbg,160),
        (agdp()*acfg()->btnroundsz)-1
      );*/
      ag_roundgrad(&d->control_pushed, wadd + 1, wadd + 1, w - (2 + wdel), h - (2 + wdel), acfg()->controlbg, acfg()->controlbg_g, (agdp()*acfg()->btnroundsz) - 1);
      ag_roundgrad_ex(&d->control_pushed, wadd + 1, wadd + 1, w - (2 + wdel), (h - (1 + wdel)) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->btnroundsz) - 1, 1, 1, 0, 0);
    }
    
    ag_textf(&d->control_pushed, txtw, txtx + 1, txty + 1, text, acfg()->controlbg, 0);
    ag_text(&d->control_pushed, txtw, txtx, txty, text, acfg()->controlfg, 0);
  }
  
  //-- Draw Focused Control
  hl1 = ag_calchighlight(acfg()->selectbg, acfg()->selectbg_g);
  ag_draw_ex(&d->control_focused, win->bg, 0, 0, x, y, w, h);
  
  if (!atheme_draw("img.button.focus", &d->control_focused, 0, 0, w, h)) {
    ag_roundgrad(&d->control_focused, wadd, wadd, w - wdel, h - wdel, acfg()->border, acfg()->border_g, (agdp()*acfg()->btnroundsz));
    //ag_roundgrad(&d->control_focused,wadd+1,wadd+1,w-(wdel+2),h-(wdel+2),acfg()->controlbg,acfg()->controlbg_g,(agdp()*acfg()->btnroundsz)-1);
    ag_roundgrad(&d->control_focused, wadd + 1, wadd + 1, w - (wdel + 2), h - (wdel + 2), acfg()->selectbg, acfg()->selectbg_g, (agdp()*acfg()->btnroundsz) - 1);
    ag_roundgrad_ex(&d->control_focused, wadd + 1, wadd + 1, w - (wdel + 2), (h - (wdel + 2)) / 2, LOWORD(hl1), HIWORD(hl1), (agdp()*acfg()->btnroundsz) - 1, 1, 1, 0, 0);
  }
  
  ag_textf(&d->control_focused, txtw, txtx + 1, txty + 1, text, acfg()->selectbg_g, 0);
  ag_text(&d->control_focused, txtw, txtx, txty, text, acfg()->selectfg, 0);
  
  if (img != NULL) {
    apng_stretch(&d->control, img, imgX, imgY, imgS, imgS, 0, 0, img->w, img->h);
    apng_stretch(&d->control_pushed, img, imgX, imgY, imgS, imgS, 0, 0, img->w, img->h);
    apng_stretch(&d->control_focused, img, imgX, imgY, imgS, imgS, 0, 0, img->w, img->h);
  }
  
  //-- Initializing Control
  if (ctl == NULL) {
    ctl  = malloc(sizeof(ACONTROL));
    ctl->ondestroy = &imgbtn_ondestroy;
    ctl->oninput  = &imgbtn_oninput;
    ctl->ondraw   = &imgbtn_ondraw;
    ctl->onblur   = &imgbtn_onblur;
    ctl->onfocus  = &imgbtn_onfocus;
    ctl->win      = win;
    ctl->forceNS  = 0;
    ctl->d        = (void *) d;
    ctl->x        = x;
    ctl->y        = y;
    ctl->w        = w;
    ctl->h        = h;
    aw_add(win, ctl);
  }
  else {
    ctl->x        = x;
    ctl->y        = y;
    ctl->w        = w;
    ctl->h        = h;
    imgbtn_ondraw(ctl);
  }
  
  return ctl;
}
ACONTROLP afbox(
  AWINDOWP win,
  int x,
  int y,
  int w,
  int h,
  byte touchmsg,
  byte holdmsg,
  byte boxtype,
  byte changemsg
){
  //-- Validate Minimum Size
  if (h<agdp()*16) h=agdp()*16;
  if (w<agdp()*20) w=agdp()*20;

  //-- Initializing Text Data
  AFBOXDP d        = (AFBOXDP) malloc(sizeof(AFBOXD));
  memset(d,0,sizeof(AFBOXD));
  
  //-- Set Signature
  d->acheck_signature = 177;
  d->touchmsg         = touchmsg;
  d->holdmsg          = holdmsg;
  d->changemsg        = changemsg;
  d->boxtype          = boxtype;
  d->lasttouch        = 0;
  d->check_n          = 0;
  
  //-- Initializing Canvas
  ag_canvas(&d->control,w,h);
  ag_canvas(&d->control_focused,w,h);
  
  int minpadding = 2;
  
  //-- Initializing Client Size
  d->clientWidth  = w-(agdp()*minpadding);
  d->clientTextW  = d->clientWidth - (agdp()*44);
  d->clientTextX  = (agdp()*26);
  
  d->client.data=NULL;
  
  //-- Draw Control
  ag_draw_ex(&d->control,&win->c,0,0,x,y,w,h);
  ag_roundgrad(&d->control,0,0,w,h,acfg()->textbg,acfg()->textbg,0);
  
  //-- 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,0);
  ag_roundgrad(&d->control_focused,1,1,w-2,h-2,acfg()->textbg,acfg()->textbg,0);
  
  //-- Set Scroll Value
  d->selectedId  = -1;
  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();
  d->draweditemn = 0;
  
  d->groupCounts = 0;
  d->groupCurrId = -1;
  
  ACONTROLP ctl = malloc(sizeof(ACONTROL));
  ctl->ondestroy= &afbox_ondestroy;
  ctl->oninput  = &afbox_oninput;
  ctl->ondraw   = &afbox_ondraw;
  ctl->onblur   = &afbox_onblur;
  ctl->onfocus  = &afbox_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 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);
    }
  }
}