/*
Copyright (C) 1996-2001 Id Software, Inc.
Copyright (C) 2002-2005 John Fitzgibbons and others
Copyright (C) 2007-2008 Kristian Duske

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "quakedef.h"

// mouse variables
cvar_t	m_filter = {"m_filter","0"};

int FilterMouseEvents (const SDL_Event *event)
{
    switch (event->type) {
        case SDL_MOUSEMOTION:
        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            return 0;
    }
    
    return 1;
}

void IN_Activate (void)
{
    if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
    {
        SDL_WM_GrabInput(SDL_GRAB_ON);
        if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
            Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_ON) failed.\n");
    }

    if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE)
    {
        SDL_ShowCursor(SDL_DISABLE);
        if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE)
            Con_Printf("WARNING: SDL_ShowCursor(SDL_DISABLE) failed.\n");
    }

    if (SDL_GetEventFilter() != NULL)
        SDL_SetEventFilter(NULL);
}

void IN_Deactivate (qboolean free_cursor)
{
    if (free_cursor)
    {
        if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF)
        {
            SDL_WM_GrabInput(SDL_GRAB_OFF);
            if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF)
                Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_OFF) failed.\n");
        }

        if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE)
        {
            SDL_ShowCursor(SDL_ENABLE);
            if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE)
                Con_Printf("WARNING: SDL_ShowCursor(SDL_ENABLE) failed.\n");
        }
    }
    
    // discard all mouse events when input is deactivated
    if (SDL_GetEventFilter() != FilterMouseEvents)
        SDL_SetEventFilter(FilterMouseEvents);
}

void IN_Init (void)
{
    BuildKeyMaps();
    
    if (SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL) == -1)
        Con_Printf("Warning: SDL_EnableKeyRepeat() failed.\n");
        
    IN_Activate();
}

void IN_Shutdown (void)
{
    IN_Deactivate(true);
}

void IN_Commands (void)
{
    // TODO:  implement this for joystick support
}

extern cvar_t cl_maxpitch; //johnfitz -- variable pitch clamping
extern cvar_t cl_minpitch; //johnfitz -- variable pitch clamping

// total accumulated mouse movement since last frame
// this gets updated from the main game loop via IN_MouseMove
int total_dx, total_dy = 0;

void IN_MouseMove(int dx, int dy)
{
    total_dx += dx;
    total_dy += dy;
}

void IN_Move (usercmd_t *cmd)
{
    int         dmx, dmy;

    /* TODO: fix this
    if (m_filter.value)
    {
        dmx = (2*mx - dmx) * 0.5;
        dmy = (2*my - dmy) * 0.5;
    }
    */

    dmx = total_dx * sensitivity.value;
    dmy = total_dy * sensitivity.value;
    
    total_dx = 0;
    total_dy = 0;

    if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
        cmd->sidemove += m_side.value * dmx;
    else
        cl.viewangles[YAW] -= m_yaw.value * dmx;

    if (in_mlook.state & 1)
        V_StopPitchDrift ();

    if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
    {
        cl.viewangles[PITCH] += m_pitch.value * dmy;
        //johnfitz -- variable pitch clamping
        if (cl.viewangles[PITCH] > cl_maxpitch.value)
            cl.viewangles[PITCH] = cl_maxpitch.value;
        if (cl.viewangles[PITCH] < cl_minpitch.value)
            cl.viewangles[PITCH] = cl_minpitch.value;
        //johnfitz
    }
    else
    {
        if ((in_strafe.state & 1) && noclip_anglehack)
            cmd->upmove -= m_forward.value * dmy;
        else
            cmd->forwardmove -= m_forward.value * dmy;
    }
}

void IN_ClearStates (void)
{
}
