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

#include "keyboard.h"
#include "l_level.h"
#include "win_raw.h"
#include "bild.h"
#include "vesa.h"
#include "d_list.h"
#include "file.h"
#include "tool.h"
#include "tprint.h"
#include "help.h"
#include "error.h"

#include "button.h"

/* globale Variablen initialisieren */
T_LISTE *button_first=NULL;
T_LISTE *button_last=NULL;
T_INT button_error=T_OK;

T_INT button_color1=0;
T_INT button_color2=0;
T_INT button_color3=0;
T_INT button_color4=0;
T_INT button_color5=0;
T_INT button_color6=0;

T_INT button_exist(T_LISTE *button_liste, T_INT id);

/***************************************************************/

T_INT move_button(WINDOW_LISTEN_ELEMENT *this_window, BUTTON *this_button, T_INT x_off, T_INT y_off)
{
 T_LISTE *button_liste=this_window->button_first;
 BUTTON_LISTEN_ELEMENT *button_element=NULL;
 T_DEBUG_ENTRY("move_button",50)
 while (button_liste!=NULL)
 {
  if (((BUTTON_LISTEN_ELEMENT *)button_liste->objekt)->button==this_button)
  {
   button_element=(BUTTON_LISTEN_ELEMENT *)button_liste->objekt;
  }
  button_liste=button_liste->naechstes;
 }
 if (button_element==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return T_NOT_OK;
 }
 button_element->x_offset=x_off;
 button_element->y_offset=y_off;
 button_element->status=INITIALISING;
 if ( ( ((this_window->art&VIRTUAL_FRONT_WINDOW)==VIRTUAL_FRONT_WINDOW) ||
        ((this_window->art&FRONT_WINDOW)==FRONT_WINDOW))
    && ((x_off<0)||(y_off<0)
        ||(x_off+this_button->breite>this_window->b_open)
        ||(y_off+this_button->hoehe>this_window->h_open) )
    )
 {
  T_INT x=x_off+this_window->x_0;
  T_INT y=y_off+this_window->y_0;
  T_INT x_len=this_button->breite;
  T_INT y_len=this_button->hoehe;
  T_INT oob=T_FALSE;
  if (x_off<0)
  {
   if (x_off+this_button->breite>0)
   {
    oob=T_TRUE;
    x=this_window->x_0;
    x_len=x_off+this_button->breite;
   }
   else
   {
    T_DEBUG_FUNCTION_POSITION(2)
    T_DEBUG_LEAVE
    return T_OK;
   }
  }
  else if (x_off+this_button->breite>this_window->b_open)
  {
   if (x_off<this_window->b_open)
   {
    oob=T_TRUE;
    x=this_window->x_0+x_off;
    x_len=this_window->b_open-x_off;
   }
   else
   {
    T_DEBUG_FUNCTION_POSITION(3)
    T_DEBUG_LEAVE
    return T_OK;
   }
  }
  if (y_off<0)
  {
   if (y_off+this_button->hoehe>0)
   {
    oob=T_TRUE;
    y=this_window->y_0;
    y_len=y_off+this_button->hoehe;
   }
   else
   {
    T_DEBUG_FUNCTION_POSITION(4)
    T_DEBUG_LEAVE
    return T_OK;
   }
  }
  else
  if (y_off+this_button->hoehe>this_window->h_open)
  {
   if (y_off<this_window->h_open)
   {
    oob=T_TRUE;
    y=this_window->y_0+y_off;
    y_len=this_window->h_open-y_off;
   }
   else
   {
    T_DEBUG_FUNCTION_POSITION(5)
    T_DEBUG_LEAVE
    return T_OK;
   }
  }
  if (oob==T_TRUE)
  {
   vesa_rect_fill(
   x+this_window->x,
   y+this_window->y,
   x_len,
   y_len,
   this_window->bcolor);
  }
  T_DEBUG_FUNCTION_POSITION(6)
  T_DEBUG_LEAVE
  return T_OK;
 }
 if (this_window!=NULL)
 {
// new
  if (button_raw==T_FALSE)
  {
   /* not checked for out of bounds with 'new' coordinates */
   button_element->x_offset+=this_window->x_0;
   button_element->y_offset+=this_window->y_0;
  }
  wprint_button(this_window,button_element,RELEASED);
 }
 else
 {
  if (x_off<0)
   button_element->x_offset=(vesa_x+x_off)-this_button->breite;
  if (y_off<0)
   button_element->y_offset=(vesa_y+y_off)-this_button->hoehe;
  bprint_button(button_element,RELEASED);
 }
 T_DEBUG_LEAVE
 return T_OK;
}

T_VOID free_button(BUTTON *button)
{
 T_DEBUG_ENTRY("free_button",50)
 if (button==NULL)
 {
  button_error=T_NOT_OK;
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return;
 }
 switch (button->art)
 {
  case TEXT:
//  case STEXT:
  case EDIT_TEXT:
  {
   if (button->name!=NULL)
   {
    free(button->name);
    button->name=NULL;
   }
   break;
  }
  case BIT_MAP:
  {
   if (button->bitmap!=NULL)
    free_mem_bild(button->bitmap);
   break;
  }
  case MEMBILD:
  {
   break;
  }
 }
 free(button);
 button=NULL;
 T_DEBUG_LEAVE
}

/***************************************************************/
T_INT execute_check_button(PARAMETER *parameter)
{
 WINDOW_LISTEN_ELEMENT *window_element=(WINDOW_LISTEN_ELEMENT *)parameter->window_element;
 BUTTON_LISTEN_ELEMENT *button_element=(BUTTON_LISTEN_ELEMENT *)parameter->button_element;
 BUTTON *button= button_element->button;
 T_DEBUG_ENTRY("execute_check_button",100)
 parameter->executed=PARAMETER_EXECUTED;
 if (fKBDisALT()==T_TRUE)
 {
  help_function("check.hlf",NULL);
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return parameter->ebene;
 }
 wprint_button(window_element,button_element,PRESSED);
 do
 {
  vesa_mouse_update();
 }
 while ((vesa_mouse_button)&&(is_mouse_on_this_button(window_element,button_element)));
 wprint_button(window_element,button_element,RELEASED);
 if (is_mouse_on_this_button(window_element,button_element))
 {
  T_INT x=button_element->x_offset;
  T_INT y=button_element->y_offset;
  if (*(button->value)==T_TRUE)
  {
   print_rectfill_with_all_features(
   window_element,
   PRINT_WIN_RAW,
   x+button->line_width+4,
   y+button->line_width+4,
   button->breite-2*button->line_width-2*4,
   button->hoehe-2*button->line_width-2*4,
   button->text_col);
   *button->value=T_FALSE;
  }
  else
  {
   print_rectfill_with_all_features(
   window_element,
   PRINT_WIN_RAW,
   x+button->line_width+4,
   y+button->line_width+4,
   button->breite-2*button->line_width-2*4,
   button->hoehe-2*button->line_width-2*4,
   button->back_col);
   *button->value=T_TRUE;
  }
 }
 T_DEBUG_LEAVE
 return parameter->ebene;
}

BUTTON *make_check_button(T_INT col_text,T_INT col_back,T_INT shade1_col,T_INT shade2_col,
                           T_INT light1_col,T_INT light2_col, T_INT line_width, T_INT taste, T_INT size_x, T_INT size_y)
{
 BUTTON *this_button=NULL;
 T_INT len_x,len_y;
 T_DEBUG_ENTRY("make_check_button",50)
 this_button=(BUTTON *)malloc(sizeof(BUTTON));
 if (this_button==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_button->notify_funktion=NULL;
 this_button->other_buttons_first=NULL;
 this_button->value=NULL;
 this_button->name=NULL;
 this_button->bitmap=NULL;
 this_button->text_col=col_text;
 this_button->back_col=col_back;
 this_button->shade1_col=shade1_col;
 this_button->shade2_col=shade2_col;
 this_button->light1_col=light1_col;
 this_button->light2_col=light2_col;
 vesa_get_text_len(" ",&len_x,&len_y);
 this_button->thickness_x=0; // 8
 this_button->thickness_y=0; // 2
 this_button->breite=size_x;
 this_button->hoehe=size_y;
 this_button->line_width=line_width;
 this_button->taste=taste;
 this_button->art=CHECK;
 this_button->schalt_art=CALL_FUNCTION_ONLY;
 this_button->button_funktion=execute_check_button;
 T_DEBUG_LEAVE
 return this_button;
}

/***************************************************************/

BUTTON *make_mem_bild_button(MEM_BILD *bild,T_INT background, T_INT shade1_col,T_INT shade2_col,T_INT light1_col,
                             T_INT light2_col, T_INT line_width, T_INT taste, T_INT schalt_art)
{
 BUTTON *this_button=NULL;
 T_DEBUG_ENTRY("make_mem_bild_button",50)
 if (bild==NULL)
 {
  button_error=BUTTON_NO_MEM_BILD;
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_button=(BUTTON *)malloc(sizeof(BUTTON));
 if (this_button==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  T_DEBUG_FUNCTION_POSITION(2)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_button->other_buttons_first=NULL;
 this_button->notify_funktion=NULL;
 this_button->value=NULL;
 this_button->name=NULL;
 this_button->bitmap=bild;
 this_button->breite=bild->x_size+2*line_width;
 this_button->hoehe=bild->y_size+2*line_width;
 this_button->hintergrund=background;
 this_button->thickness_x=0;
 this_button->thickness_y=0;
 this_button->text_col=0;
 this_button->back_col=0;
 this_button->shade1_col=shade1_col;
 this_button->shade2_col=shade2_col;
 this_button->light1_col=light1_col;
 this_button->light2_col=light2_col;
 this_button->line_width=line_width;
 this_button->taste=taste;
 this_button->art=MEMBILD;
 this_button->schalt_art=schalt_art;
 this_button->button_funktion=NULL;
 T_DEBUG_LEAVE
 return this_button;
}

/***************************************************************/

BUTTON *make_bitmap_button(T_PCHAR name,T_INT background, T_INT shade1_col,T_INT shade2_col,T_INT light1_col,
                            T_INT light2_col, T_INT line_width, T_INT taste, T_INT schalt_art)
{
 BUTTON *this_button=NULL;
 MEM_BILD *bild;
 T_PCHAR current_path=NULL;
 T_DEBUG_ENTRY("make_bitmap_button",50)
 if (f_file_exist( name )==T_FALSE)
 {
  current_path=get_current_path();
  if (tool_pfad!=NULL)
   change_directory(tool_pfad);
  name="default.pcx";
  if (f_file_exist( name )==T_FALSE)
  {
   if (current_path!=NULL)
   {
    change_directory(current_path);
    free(current_path);
   }
   show_message("Kann Bitmap button mit Bitmap:\n\"%s\"\nnicht erstellen.",name);
   button_error=BUTTON_DEFAULT_BITMAPS_NOT_FOUND;
   T_DEBUG_FUNCTION_POSITION(1)
   T_DEBUG_LEAVE
   return NULL;
  }
 }
 bild=lade_pcx_nach_mem(name,ALL_MEM_OK);
 if (current_path!=NULL)
 {
  change_directory(current_path);
  free(current_path);
 }
 if (bild==NULL)
 {
  button_error=BUTTON_LOAD_BITMAP_ERROR;
  T_DEBUG_FUNCTION_POSITION(2)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_button=(BUTTON *)malloc(sizeof(BUTTON));
 if (this_button==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  T_DEBUG_FUNCTION_POSITION(3)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_button->other_buttons_first=NULL;
 this_button->notify_funktion=NULL;
 this_button->value=NULL;
 this_button->name=NULL;
 this_button->bitmap=bild;
 this_button->breite=bild->x_size+2*line_width;
 this_button->hoehe=bild->y_size+2*line_width;
 this_button->hintergrund=background;
 this_button->text_col=0;
 this_button->back_col=0;
 this_button->thickness_x=0;
 this_button->thickness_y=0;
 this_button->shade1_col=shade1_col;
 this_button->shade2_col=shade2_col;
 this_button->light1_col=light1_col;
 this_button->light2_col=light2_col;
 this_button->line_width=line_width;
 this_button->taste=taste;
 this_button->art=BIT_MAP;
 this_button->schalt_art=schalt_art;
 this_button->button_funktion=NULL;
 T_DEBUG_LEAVE
 return this_button;
}

/***************************************************************/

BUTTON *make_edit_text_button_(T_PCHAR text, T_INT maxlen, T_INT col_text,T_INT col_back,T_INT shade1_col,
                              T_INT shade2_col,T_INT light1_col,T_INT light2_col, T_INT line_width, T_INT taste, T_INT schalt_art, T_INT thickness_x, T_INT thickness_y)
{
 BUTTON *this_button=NULL;
 T_PCHAR this_text=NULL;
 T_DEBUG_ENTRY("make_edit_text_button",50)
 this_button=(BUTTON *)malloc(sizeof(BUTTON));
 if (this_button==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 this_text=(T_PCHAR )malloc(maxlen+1); /* +1 wegen 0 */
 if (this_text==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  free(this_button);
  T_DEBUG_FUNCTION_POSITION(2)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 if (text!=NULL)
  strncpy(this_text,text,maxlen);
 else
  this_text[0]=0;
 this_button->notify_funktion=NULL;
 this_button->other_buttons_first=NULL;
 this_button->value=NULL;
 this_button->name=this_text;
 this_button->bitmap=NULL;
 this_button->text_col=col_text;
 this_button->back_col=col_back;
 this_button->shade1_col=shade1_col;
 this_button->shade2_col=shade2_col;
 this_button->light1_col=light1_col;
 this_button->light2_col=light2_col;
 this_button->thickness_x=thickness_x; // 8
 this_button->thickness_y=thickness_y; // 2
 this_button->breite=font_now->zeichen['m'].breite*maxlen+2*thickness_x+2*line_width;
 this_button->hoehe=font_now->zeichen[' '].hoehe+2*thickness_y+2*line_width;
 this_button->line_width=line_width;
 this_button->taste=taste;
 this_button->art=EDIT_TEXT;
 this_button->schalt_art=schalt_art;
 this_button->button_funktion=NULL;
 T_DEBUG_LEAVE
 return this_button;
}

/***************************************************************/

BUTTON *make_text_button_(T_PCHAR text,T_INT col_text,T_INT col_back,T_INT shade1_col,T_INT shade2_col,
                           T_INT light1_col,T_INT light2_col, T_INT line_width, T_INT taste, T_INT schalt_art, T_INT thickness_x, T_INT thickness_y)
{
 BUTTON *this_button=NULL;
 T_PCHAR this_text=NULL;
 T_INT len_x,len_y;
 T_DEBUG_ENTRY("make_text_button_",50)
 this_button=(BUTTON *)malloc(sizeof(BUTTON));
 if (this_button==NULL)
 {
  button_error=GENERIC_MEMORY_NOT_AVAILABLE;
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return NULL;
 }
 if (text!=NULL)
 {
  this_text=(T_PCHAR )malloc(strlen(text)+1);
  if (this_text==NULL)
  {
   button_error=GENERIC_MEMORY_NOT_AVAILABLE;
   free(this_button);
   T_DEBUG_FUNCTION_POSITION(2)
   T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
   T_DEBUG_LEAVE
   return NULL;
  }
  strcpy(this_text,text);
 }
 this_button->notify_funktion=NULL;
 this_button->other_buttons_first=NULL;
 this_button->value=NULL;
 this_button->name=this_text;
 this_button->bitmap=NULL;
 this_button->text_col=col_text;
 this_button->back_col=col_back;
 this_button->shade1_col=shade1_col;
 this_button->shade2_col=shade2_col;
 this_button->light1_col=light1_col;
 this_button->light2_col=light2_col;
 vesa_get_text_len(text,&len_x,&len_y);
 this_button->thickness_x=thickness_x; // 8
 this_button->thickness_y=thickness_y; // 2
 this_button->breite=len_x+2*thickness_x+2*line_width; // 16
 this_button->hoehe=len_y+2*thickness_y+2*line_width; // 4
 this_button->line_width=line_width;
 this_button->taste=taste;
 this_button->art=TEXT;
 this_button->schalt_art=schalt_art;
 this_button->button_funktion=NULL;
 T_DEBUG_LEAVE
 return this_button;
}

/***************************************************************/

/* liefert einen wahrheitswert, ob sich die maus auf dem angegebenen button */
/* befinden */
T_INT is_mouse_on_this_button(WINDOW_LISTEN_ELEMENT *this_window,BUTTON_LISTEN_ELEMENT *this_button)
{
 T_INT m_x=vesa_mouse_x,m_y=vesa_mouse_y;
 T_DEBUG_ENTRY("is_mouse_on_this_button",50)
 if (this_button==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return T_FALSE;
 }
 if (this_window==NULL)
 {
  if ( ((m_x>this_button->x_offset)
  &&    (m_x<this_button->x_offset+this_button->button->breite))
  &&(   (m_y>+this_button->y_offset)&&
        (m_y<this_button->y_offset+this_button->button->hoehe)))
  {
   T_DEBUG_FUNCTION_POSITION(2)
   T_DEBUG_LEAVE
   return T_TRUE;
  }
 }
 else
 {
  if ( ((m_x>this_window->x+this_button->x_offset)
  &&(m_x<this_window->x+this_button->x_offset+this_button->button->breite))
  &&((m_y>this_window->y+this_button->y_offset)
  &&(m_y<this_window->y+this_button->y_offset+this_button->button->hoehe)))
  {
   T_DEBUG_FUNCTION_POSITION(3)
   T_DEBUG_LEAVE
   return T_TRUE;
  }
 }
 T_DEBUG_LEAVE
 return T_FALSE;
}

/***************************************************************/

/* wenn die maus sich auf einem bestimmten fenster befindet, kann man */
/* hiermit den button ermitteln, auf dem sich der mauszeiger befindet */
/* es wird der button oder NULL zurueckgegeben */
BUTTON_LISTEN_ELEMENT *is_mouse_on_button(WINDOW_LISTEN_ELEMENT *test_window)
{
 T_INT m_x=vesa_mouse_x,m_y=vesa_mouse_y;
 T_LISTE *button_liste;
 BUTTON_LISTEN_ELEMENT *button;
 T_DEBUG_ENTRY("is_mouse_on_button",50)
 if (test_window != NULL)
 {
  button_liste=test_window->button_first;
  while (button_liste!=NULL)
  {
   button=(BUTTON_LISTEN_ELEMENT *) button_liste->objekt;
   if ( ((m_x>test_window->x+button->x_offset)&&
         (m_x<test_window->x+button->x_offset+button->button->breite))&&(
         (m_y>test_window->y+button->y_offset)&&
         (m_y<test_window->y+button->y_offset+button->button->hoehe)))
   {
    T_DEBUG_FUNCTION_POSITION(1)
    T_DEBUG_LEAVE
    return button;
   }
   button_liste=button_liste->naechstes;
  }
 }
 else
 {
  button_liste=button_first;
  while (button_liste!=NULL)
  {
   button=(BUTTON_LISTEN_ELEMENT *) button_liste->objekt;
   if ( ((m_x>button->x_offset)
   &&    (m_x<button->x_offset+button->button->breite))
   &&(   (m_y>button->y_offset)
   &&    (m_y<button->y_offset+button->button->hoehe)))
   {
    T_DEBUG_FUNCTION_POSITION(2)
    T_DEBUG_LEAVE
    return button;
   }
   button_liste=button_liste->naechstes;
  }
 }
 T_DEBUG_LEAVE
 return NULL;
}

/***************************************************************/

T_INT button_exist(T_LISTE *button_liste, T_INT id)
{
 T_DEBUG_ENTRY("button_exist",50)
 while (button_liste!=NULL)
 {
  if (((BUTTON_LISTEN_ELEMENT *)(button_liste->objekt))->id==id)
  {
   T_DEBUG_FUNCTION_POSITION(1)
   T_DEBUG_LEAVE
   return T_TRUE;
  }
  button_liste=button_liste->naechstes;
 }
 T_DEBUG_LEAVE
 return T_FALSE;
}

/***************************************************************/

T_INT add_button(WINDOW_LISTEN_ELEMENT *this_window, BUTTON *this_button,T_INT x_off,T_INT y_off, T_INT b_id)
{
 T_LISTE *button_liste;
 BUTTON_LISTEN_ELEMENT *button;
 static T_INT id=1;
 T_DEBUG_ENTRY("add_button",50)
 if (id==0)
  id=1;
 if (this_button==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return T_NOT_OK;
 }
 if (this_window!=NULL)
  button_liste=this_window->button_first;
 else
  button_liste=button_first;
 if (b_id!=0)
 {
  if (button_exist(button_liste,b_id)==T_TRUE)
  {
   button_error=BUTTON_DOUBLE_ID;
   T_DEBUG_FUNCTION_POSITION(2)
   T_DEBUG_SET_THIS_FUNCTION_ERROR(BUTTON_DOUBLE_ID)
   T_DEBUG_LEAVE
   return T_NOT_OK;
  }
  id=b_id;
 }
 while (button_exist(button_liste,id))
 {
  id++;
  if (id==0)
   id=1;
 }
 // jetzt eindeutige id da
 if (this_button->art==CHECK)
 {
  if (this_button->value==NULL)
  {
   T_DEBUG_FUNCTION_POSITION(3)
   T_DEBUG_SET_THIS_FUNCTION_ERROR(NO_VALUE_FOR_CHECK_BUTTON)
   T_DEBUG_LEAVE
   return NO_VALUE_FOR_CHECK_BUTTON;
  }
 }
 button=(BUTTON_LISTEN_ELEMENT *)malloc(sizeof(BUTTON_LISTEN_ELEMENT));
 if (button==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(4)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(GENERIC_MEMORY_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return GENERIC_MEMORY_NOT_AVAILABLE;
 }
 button->button=this_button;
 button->x_offset=x_off;
 button->y_offset=y_off;
 button->id=id;
 button->status=INITIALISING;
 if (this_window!=NULL)
 {
  if (x_off<0)
   button->x_offset=(this_window->b+x_off)-this_button->breite;
  if (y_off<0)
   button->y_offset=(this_window->h+y_off)-this_button->hoehe;
  d_fuege_in_liste_ein(button,&(this_window->button_first),&(this_window->button_last),DL_HINTEN);
// new
  if (button_raw==T_FALSE)
  {
   /* not checked for out of bounds with 'new' coordinates */
   button->x_offset+=this_window->x_0;
   button->y_offset+=this_window->y_0;
  }
  if ((button->x_offset>=0)&&(this_button->breite+button->x_offset<this_window->b-this_window->border_r))
   if ((button->y_offset>=0)&&(this_button->hoehe+button->y_offset<this_window->h-this_window->border_u))
    wprint_button(this_window,button,RELEASED);
 }
 else
 {
  if (x_off<0)
   button->x_offset=(vesa_x+x_off)-this_button->breite;
  if (y_off<0)
   button->y_offset=(vesa_y+y_off)-this_button->hoehe;
  d_fuege_in_liste_ein(button,&button_first,&button_last,DL_HINTEN);
  bprint_button(button,RELEASED);
 }
 T_DEBUG_LEAVE
 return T_OK;
}

/***************************************************************/

T_VOID delete_all_buttons(WINDOW_LISTEN_ELEMENT *this_window)
{
 T_DEBUG_ENTRY("delete_all_buttons",50)
 if (this_window==NULL)
 {
  while (button_first!=NULL)
   delete_button_id(NULL,((BUTTON_LISTEN_ELEMENT *)(button_first->objekt))->id,DELETE_BUTTON);
 }
 else
 {
  while (this_window->button_first!=NULL)
   delete_button_id(this_window,((BUTTON_LISTEN_ELEMENT *)
   (this_window->button_first->objekt))->id,DELETE_BUTTON);
 }
 T_DEBUG_LEAVE
}

/***************************************************************/

T_INT delete_button_id(WINDOW_LISTEN_ELEMENT *this_window, T_INT button_id, T_INT flag)
{
 T_LISTE *button_liste;
 BUTTON_LISTEN_ELEMENT *listen_element;
 T_DEBUG_ENTRY("delete_button_id",50)
 if (this_window==NULL)
  button_liste=button_first;
 else
  button_liste=this_window->button_first;
 while ((button_liste!=NULL)&&((((BUTTON_LISTEN_ELEMENT *)button_liste->objekt))->id!=button_id))
  button_liste=button_liste->naechstes;
 if (button_liste==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(BUTTON_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return BUTTON_NOT_AVAILABLE;
 }
 listen_element=(BUTTON_LISTEN_ELEMENT *)button_liste->objekt;
 if (this_window==NULL)
  d_entferne_aus_liste(((BUTTON_LISTEN_ELEMENT *)button_liste->objekt),&button_first,&button_last,DL_CLEAN_UP);
 else
  d_entferne_aus_liste(((BUTTON_LISTEN_ELEMENT *)button_liste->objekt),
  &(this_window->button_first),&(this_window->button_last),DL_CLEAN_UP);
 if (flag==DELETE_BUTTON)
  free_button(listen_element->button);
 free(listen_element);
 T_DEBUG_LEAVE
 return T_OK;
}

/***************************************************************/

T_INT delete_button(WINDOW_LISTEN_ELEMENT *this_window, BUTTON *button, T_INT flag)
{
 T_LISTE *button_liste;
 BUTTON_LISTEN_ELEMENT *listen_element;
 T_DEBUG_ENTRY("delete_button",50)
 if (button==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_SET_THIS_FUNCTION_ERROR(BUTTON_NOT_AVAILABLE)
  T_DEBUG_LEAVE
  return BUTTON_NOT_AVAILABLE;
 }
 if (this_window==NULL)
  button_liste=button_first;
 else
  button_liste=this_window->button_first;
 while ((button_liste!=NULL)&&((((BUTTON_LISTEN_ELEMENT *)button_liste->objekt))->button!=button))
  button_liste=button_liste->naechstes;
 if (button_liste==NULL)
 {
  T_DEBUG_FUNCTION_POSITION(2)
  T_DEBUG_LEAVE
  T_DEBUG_SET_THIS_FUNCTION_ERROR(BUTTON_NOT_AVAILABLE)
  return BUTTON_NOT_AVAILABLE;
 }
 listen_element=(BUTTON_LISTEN_ELEMENT *)button_liste->objekt;
 if (this_window==NULL)
  d_entferne_aus_liste(((BUTTON_LISTEN_ELEMENT *)button_liste->objekt),&button_first,&button_last,DL_CLEAN_UP);
 else
  d_entferne_aus_liste(((BUTTON_LISTEN_ELEMENT *)button_liste->objekt),&(this_window->button_first),
  &(this_window->button_last),DL_CLEAN_UP);
 if (flag==DELETE_BUTTON)
  free_button(button);
 free(listen_element);
 T_DEBUG_LEAVE
 return T_OK;
}

/***************************************************************/

