/************************************************************************/
/*                                                                      */
/*    vspline - a set of generic tools for creation and evaluation      */
/*              of uniform b-splines                                    */
/*                                                                      */
/*            Copyright 2015 - 2023 by Kay F. Jahnke                    */
/*                                                                      */
/*    The git repository for this software is at                        */
/*                                                                      */
/*    https://bitbucket.org/kfj/vspline                                 */
/*                                                                      */
/*    Please direct questions, bug reports, and contributions to        */
/*                                                                      */
/*    kfjahnke+vspline@gmail.com                                        */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

/*! \file use_map.cc

    \brief test program for code in map.h
    
    The program creates one gate type each of the types provided in map.h
    over the interval [0,1]. Then it queries a value and uses the gates on
    this value in turn, printing out the result.
*/

#include <iostream>
#include <iomanip>
#include <assert.h>
#include <vspline/map.h>

const int VSIZE = vspline::vector_traits < double > :: size ;

template < class gate_type >
void test ( gate_type gx , double x , const char * mode )
{
  std::cout << mode << std::endl ;

  auto tester = vspline::mapper < typename gate_type::in_type > ( gx ) ;
  
  typedef double crd_type ;

  const crd_type crd { x } ;
  crd_type res ;
  
  tester.eval ( crd , res ) ;
  
  std::cout << "single-value operation:" << std::endl ;
  
  std::cout << crd << " -> " << res << std::endl ;

  if ( VSIZE > 1 )
  {
    typedef vspline::vector_traits < crd_type , VSIZE > :: ele_v crd_v ;

    crd_v inv ( crd ) ;
    crd_v resv ;
    
    tester.eval ( inv , resv ) ;
    std::cout << "vectorized operation:" << std::endl
              << inv << " -> " << resv << std::endl ;
  }
}

int main ( int argc , char * argv[] )
{
  double x ;
  
  std::cout << std::fixed << std::showpos << std::showpoint
            << std::setprecision(5);
            
  while ( std::cin.good() )
  {
    std::cout << "enter coordinate to map to [ 0.0 : 1.0 ]" << std::endl ;
    std::cin >> x ;

    if ( std::cin.eof() )
    {
      std::cout << std::endl ;
      break ;
    }

    try
    {
      test ( vspline::reject ( 0.0 , 1.0 ) ,
             x , "REJECT:" ) ;
    }
    catch ( vspline::out_of_bounds )
    {
      std::cout << "exception out_of_bounds" << std::endl ;
    }
    test ( vspline::clamp ( 0.0 , 1.0 , 0.0 , 1.0 ) ,
           x , "CLAMP:" ) ;
           
    test ( vspline::mirror ( 0.0 , 1.0 ) ,
           x , "MIRROR:" ) ;
           
    test ( vspline::periodic ( 0.0 , 1.0 ) ,
           x , "PERIODIC:" ) ;
  }
}
