/*
     PLIB - A Suite of Portable Game Libraries
     Copyright (C) 1998,2002  Steve Baker

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later version.

     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 GNU
     Library General Public License for more details.

     You should have received a copy of the GNU Library General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

     For further information visit http://plib.sourceforge.net

     $Id: js.h,v 1.1 2007/01/02 21:48:42 jsd Exp jsd $
*/

#ifndef __INCLUDED_JS_H__
#define __INCLUDED_JS_H__ 1
#define JS_NEW

#ifndef _INCLUDED_UL_H_
#  include "ul.h"
#endif

//////////////
// JS_SHIFT was originally a DfT (Design for Test) feature.
// Specifically, it allows testing of the software, including
// the features that involve high-numbered buttons (>=32)
// even if the test platform has only a smaller number of
// actual buttons.
// It works like this:  If button #0 is depressed, all the
// the buttons numbered higher than that are shifted
// JS_SHIFT places.  So if JS_SHIFT=24, button #5 acts like
// virtual button #29 whenever button #0 is pressed.

// The results can be slightly counterintuitive if you
// perform the following sequence, assuming button #5 is
// supposedly a "momentary" button:
//	press_0, press_5, release_0, release_5
// Bit 29 is now set, and will stay set, because no events
// are being generated that would unset it.  This may be
// counterintuitive to some users, depending on what mental
// model the have of how "momentary" switches are supposed
// to work.  

#ifndef JS_SHIFT
#  define JS_SHIFT 0
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // -dw- for memcpy

#define _JS_MAX_AXES 16
#define _JS_MAX_BUTTONS 32
#define _JS_MAX_HATS 4

#define JS_TRUE  1
#define JS_FALSE 0

using namespace std;
#include <vector>

typedef vector<bool> v_bool;
typedef vector<float> v_float;

class jsJoystick
{
  int          id ;
protected:
  struct os_specific_s *os ;
  friend struct os_specific_s ;
  int          error        ;
  char         name [ 128 ] ;
  int          num_axes     ;
  int          num_buttons  ;

  v_float dead_band;
  v_float saturate;
  v_float center;
  v_float max;
  v_float min;

  void open () ;
  void close () ;

  float fudge_axis ( float value, int axis ) const ;

public:

  jsJoystick ( int ident = 0 ) ;
  ~jsJoystick () { close () ; }

  const char* getName () const { return name ;     }
  int   getNumButtons () const { return num_buttons + JS_SHIFT ; }
  int   getNumAxes    () const { return num_axes ; }
  int   notWorking    () const { return error ;    }
  void  setError      () { error = JS_TRUE ; }

  float getDeadBand ( int axis ) const       { return dead_band [ axis ] ; }
  void  setDeadBand ( int axis, float db )   { dead_band [ axis ] = db   ; }

  float getSaturation ( int axis ) const     { return saturate [ axis ]  ; }
  void  setSaturation ( int axis, float st ) { saturate [ axis ] = st    ; }

  void setsome( const v_float& from,  float* axes ) {
    for (int ii = 0; ii < num_axes; ii++){
      axes[ii] = from[ii];
    }
  }

  void getsome( const float* axes, v_float& to ) {
    for (int ii = 0; ii < num_axes; ii++){
      to[ii] = axes[ii];
    }
  }

  void setMinRange    ( float *axes ) { setsome( min, axes); }
  void setMaxRange    ( float *axes ) { setsome( max, axes); }
  void setCenterRange ( float *axes ) { setsome( center, axes); }

  void getMinRange    ( float *axes ) { getsome( axes, min); }
  void getMaxRange    ( float *axes ) { getsome( axes, max); }
  void getCenterRange ( float *axes ) { getsome( axes, center); }

  void read    ( int *buttons, float *axes ) ;
  void read    ( v_bool& buttons, v_float& axes ) ;
  void rawRead ( int *buttons, float *axes ) ;
  void rawRead ( v_bool& buttons, v_float& axes ) ;
  // bool SetForceFeedBack ( int axe, float force );
} ;

extern void jsInit () ;

#endif


