/*************************************************************************
 *                                                                       *
 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
 * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
 *                                                                       *
 * This library is free software; you can redistribute it and/or         *
 * modify it under the terms of EITHER:                                  *
 *   (1) The GNU Lesser General Public License as published by the Free  *
 *       Software Foundation; either version 2.1 of the License, or (at  *
 *       your option) any later version. The text of the GNU Lesser      *
 *       General Public License is included with this library in the     *
 *       file LICENSE.TXT.                                               *
 *   (2) The BSD-style license that is included with this library in     *
 *       the file LICENSE-BSD.TXT.                                       *
 *                                                                       *
 * This library 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 files    *
 * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
 *                                                                       *
 *************************************************************************/

// main window and event handling for X11

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <GL/glx.h>

#include "DPRSim.hxx"
#include "WorldBuilder.hxx"
#include "graphics.h"
#include "internal.h"

extern WorldBuilder builder;
extern bool buildmode;

int handleKeyPress(KeySym key, bool ctrl) {
  if (!ctrl) {
    switch (key) {
    case XK_Left:
      dsMotion(2, 50, 0); return true;
    case XK_Right:
      dsMotion(2, -50, 0); return true;
    case XK_Up:
      dsMotion(3, 50, 0); return true;
    case XK_Down:
      dsMotion(3, -50, 0); return true;
    }
  }
  else {                 // CTRL + key
    switch (key) {
    case XK_Up:
      frame_skip_count++; 
      return true;
    case XK_Down:
      frame_skip_count = (frame_skip_count > 0) ? frame_skip_count-1 : 0; 
      return true;
    case 't': case 'T':
      dsSetTextures(dsGetTextures() ^ 1);
      return true;
    case 'n': case 'N':
      dsSetNum(dsGetNum() ^ 1);
      return true;
    case 's': case 'S':
      dsSetShadows(dsGetShadows() ^ 1);
      return true;
    case 'h': case 'H':
      dsSetHud(dsGetHud() ^ 1);
      return true;
    case 'e': case 'E':
      dsSetSpeech(dsGetSpeech() ^ 1);
      return true;
    case 'c': case 'C':
      buildmode = true;
      simStop();
      return true;
    case 'x': case 'X':
      simStop();
      return true;
    case 'p': case 'P':
      simPause(simGetPaused() ^ 1);
      return true;
    case 'o': case 'O':
      if (simGetPaused())
	simAdvanceSteps(1);
      return true;
    case 'v': case 'V':
      float xyz[3], hpr[3];
      dsGetViewpoint(xyz, hpr);
      printf("ViewPoint:\nCAMERA_XYZ=%.4f,%.4f,%.4f\nCAMERA_HPR=%.4f,%.4f,%.4f\n",
	     xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2]);
      return true;
    case 'w': case 'W':
      writeframes ^= 1;
      if (writeframes)
	printf("Now writing frames to PNG files in frame directory.\n");
      return true;
    }
  }
  return false;
}

static int mode = 0;
static int mx = 0, my = 0;

void handleMouseClick(unsigned int button, int x, int y) {
  if(building() && builder.buttonPressed(button,x,y)) {
    return;
  }
  
  switch (button) {
  case Button1:
    float selPos[4];
    float selVec[4];
    convert2Dto3D(x, y, selPos, selVec);
    selectCallback(selPos[0], selPos[1], selPos[2], selVec[0], selVec[1], selVec[2]);
    break;            
  case Button2:
    mode |= 4;
    break;
  case Button3:
    mode |= 1;
    break;
  case Button4:
    dsMotion(2, 0, -50);
    break;
  case Button5:
    dsMotion(2, 0, 50);
    break;
  }
  mx = x;
  my = y;
}

void handleMouseRelease(unsigned int button, int x, int y) {
  switch(button) {
  case Button2:
    mode &= (~4);
    break;
  case Button3:
    mode &= (~1);
    break;
  }
}

void handleMouseMotion(int x, int y) {
  if(building() && builder.mouseMoved(x,y)) {
    return;
  }
  
  if (mode != 0) {
    dsMotion(mode, mx - x, my - y);
  }
  mx = x;
  my = y;
}

