/* Copyright (c) 2018
   Charles Jordan (Hokkaido University, Sapporo, Japan),
   Michael Joswig, Lars Kastner (Technische Universitaet Berlin, Germany)

   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 3, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   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.
-----------------------------------------------------------------------------
*/

#ifndef FLIP_CHECKER_HH
#define FLIP_CHECKER_HH

#include "RegularityCheckCache.hh"
#include "CommandlineOptions.hh"



class YesChecker {
   public:
      typedef std::false_type checkRegular;
      typedef YesChecker Initial;
      
      YesChecker(const PointConfiguration& points, const Chirotope& chiro){}

      bool isValid(const TriangNode& source, const TriangNode& target, const gkz_vector_type& flip_gkz) const {
         return true;
      }

      bool isGoodNode(const TriangNode& triang) const{
         return false;
      }
};

template<typename checkFine, bool keepFirstFixed>
class NonRegularChecker {

   public:
      typedef std::false_type checkRegular;
      typedef NonRegularChecker<checkFine, false> Initial;
      
      NonRegularChecker(const PointConfiguration& points, const Chirotope& chiro){}

      bool isValid(const TriangNode& source, const TriangNode& target, const gkz_vector_type& flip_gkz) const {
         if(keepFirstFixed){
            if(!fixesFirstGKZCoord<checkFine>(flip_gkz)){ return false;}
         }
         return isGoodNode(target);
      }
      
      bool isGoodNode(const TriangNode& triang) const{
         if(checkFine::value){
            if(!isFine(triang)){ return false;}
         }
         return true;
      }

};


template<typename checkFine, bool keepFirstFixed>
class RegularChecker {

   private:
      const RegularityCheckCache rcc;

   public:
      typedef std::true_type checkRegular;
      typedef RegularChecker<checkFine, false> Initial;
      
      RegularChecker(const PointConfiguration& points, const Chirotope& chiro):
         rcc(CommandlineOptions::regularity_cache_size(), points, chiro, CommandlineOptions::polymake_lp_client())
         {}
      
      RegularChecker(const int n, const PointConfiguration& points, const Chirotope& chiro):
         rcc(n, points, chiro, CommandlineOptions::polymake_lp_client())
         {}

      bool isValid(const TriangNode& source, const TriangNode& target, const gkz_vector_type& flip_gkz) const {
         if(keepFirstFixed){
            if(!fixesFirstGKZCoord<checkFine>(flip_gkz)){ return false;}
         }
         return isGoodNode(target);
      }
      
      bool isGoodNode(const TriangNode& triang) const{
         if(checkFine::value){
            if(!isFine(triang)){ return false;}
         }
         return rcc.isRegular(triang);
      }
};

#endif


