/* message.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2001-2004,2010 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "message.h"
#include "lowlevelfunc.h"
#include "fieldlvrowdata.h"
#include "aguix.h"

Message *AGUIX_allocMessage()
{
  Message *msg;

  msg = (Message*)_allocsafe( sizeof( Message ) );
  memset( msg, 0, sizeof( Message ) );
  msg->specialType = Message::NONE;
  msg->lockElement = NULL;
  msg->ack = false;
  msg->loop = 0;
  msg->keybuf = NULL;
  msg->internal = false;
  return msg;
}

void AGUIX_freeMessage( Message *msg )
{
  if ( msg != NULL ) {
    if ( msg->keybuf != NULL ) _freesafe( msg->keybuf );
    _freesafe( msg );
  }
}

AGMessage *AGUIX_allocAGMessage()
{
  AGMessage *agmsg;

  agmsg = (AGMessage*)_allocsafe( sizeof( AGMessage ) );

  memset( &agmsg->dnd, 0, sizeof( agmsg->dnd ) );
  
  agmsg->type = AG_NONE;
  agmsg->key.keybuf = NULL;
  agmsg->popupmenu.recursive_ids = NULL;
  agmsg->popupmenu.edit_content = NULL;
  return agmsg;
}

void AGUIX_freeAGMessage( AGMessage *agmsg )
{
    if ( agmsg != NULL ) {
        if ( ( agmsg->type == AG_KEYPRESSED ) || ( agmsg->type == AG_KEYRELEASED ) ) {
            if ( agmsg->key.keybuf != NULL ) _freesafe( agmsg->key.keybuf );
        }
        if ( agmsg->type == AG_DND_END ) {
            if ( agmsg->dnd.specialinfo.rowDataP != NULL ) {
                delete (agmsg->dnd.specialinfo.rowDataP);
            }
            delete agmsg->dnd.specialinfo.external_data;
        }
    
        if ( agmsg->type == AG_POPUPMENU_CLICKED ||
             agmsg->type == AG_POPUPMENU_CLOSED ||
             agmsg->type == AG_POPUPMENU_ENTRYEDITED ) {
            if ( agmsg->popupmenu.recursive_ids != NULL ) {
                delete agmsg->popupmenu.recursive_ids;
            }
            if ( agmsg->popupmenu.edit_content != NULL ) {
                delete agmsg->popupmenu.edit_content;
            }
        }

        if ( agmsg->type == AG_PASTE_FILE_LIST ) {
            delete agmsg->paste.file_list;
        }
    
        _freesafe( agmsg );
    }
}

AGMessage *AGUIX_allocAGMessage( Message *msg )
{
  AGMessage *agmsg;

  agmsg = AGUIX_allocAGMessage();
  switch( msg->type ) {
    case KeyPress:
      agmsg->type = AG_KEYPRESSED;
    case KeyRelease:
      if ( agmsg->type == AG_NONE ) agmsg->type = AG_KEYRELEASED;
      agmsg->key.window = msg->window;
      agmsg->key.key = msg->key;
      agmsg->key.keystate = msg->keystate;
      agmsg->key.keybuf = dupstring( msg->keybuf );
      agmsg->key.time = msg->time;
      break;
    case ButtonPress:
      agmsg->type = AG_MOUSEPRESSED;
    case ButtonRelease:
      if ( agmsg->type == AG_NONE ) agmsg->type = AG_MOUSERELEASED;
      agmsg->mouse.window = msg->window;
      agmsg->mouse.button = msg->button;
      agmsg->mouse.x = msg->mousex;
      agmsg->mouse.y = msg->mousey;
      agmsg->mouse.time = msg->time;
      break;
    case MotionNotify:
      agmsg->type = AG_MOUSEMOVE;
      agmsg->mouse.window = msg->window;
      /* button is wrong -> use queryPointer */
      agmsg->mouse.button = 0;
      agmsg->mouse.x = msg->mousex;
      agmsg->mouse.y = msg->mousey;
      break;
    case Expose:
      agmsg->type = AG_EXPOSE;
      agmsg->expose.window = msg->window;
      agmsg->expose.x = msg->x;
      agmsg->expose.y = msg->y;
      agmsg->expose.w = msg->width;
      agmsg->expose.h = msg->height;
      break;
    case ClientMessage:
      if ( msg->gadgettype == CLOSE_GADGET ) {
        agmsg->type = AG_CLOSEWINDOW;
        agmsg->closewindow.window = msg->window;
      } else if ( msg->specialType == Message::XIMSTUCK ) {
          agmsg->type = AG_CLIENT_MESSAGE;
          agmsg->clientmessage.cm_type = CM_XIM_STUCK;
      }
      break;
    case EnterNotify:
      agmsg->type = AG_ENTERWINDOW;
    case LeaveNotify:
      if ( agmsg->type == AG_NONE ) agmsg->type = AG_LEAVEWINDOW;
      agmsg->cross.window = msg->window;
      break;
  }
  
  return agmsg;
}
