/*-----------------------------------------------------------------------------

Copyright (C) 2012

A. Ronald Gallant
Post Office Box 659
Chapel Hill NC 27514
USA

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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

-----------------------------------------------------------------------------*/

#include "libscl.h"
#include "craps.h"

using namespace std;
using namespace scl;

namespace craps {

  payoff_t pass_line_only::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
     return payoff_t(0,0);
    }
    else {
      bets.push_back(new pass_line_bet(n,5));
      return payoff_t(0,-5);
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }
  
  payoff_t pass_line_with_odds::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
      list<bet_base*>::iterator bets_itr = bets.begin();
      while(bets_itr != bets.end()) {
        bet_base* bet_ptr = *bets_itr++;
        if (bet_ptr->get_name()=="pass_line_bet" && bet_ptr->get_odds()==0) {
          switch (marker.point) {
            case  4 :
            case 10 :
              return bet_ptr->player_action(roll,marker,3*bet_ptr->get_bet());
              break;
            case 5 :
            case 9 :
              return bet_ptr->player_action(roll,marker,4*bet_ptr->get_bet());
              break;
            case 6 :
            case 8 :
              return bet_ptr->player_action(roll,marker,5*bet_ptr->get_bet());
              break;
            default :
              return payoff_t(0, 0);
              break;
          }    
        }   
        else {
          return payoff_t(0, 0);
        }
      }
    }
    else {
      bets.push_back(new pass_line_bet(n,5));
      return payoff_t(0, -5);
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }

  payoff_t come_bet_only::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
      bets.push_back(new come_bet(n,5));
      return payoff_t(0,-5);
    }
    else {
      return payoff_t(0,0);
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }
  
  payoff_t come_bet_with_odds::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
      payoff_t payoff(0, 0);
      list<bet_base*>::iterator bets_itr = bets.begin();
      while(bets_itr != bets.end()) {
        bet_base* bet_ptr = *bets_itr++;
        if (bet_ptr->get_name()=="come_bet" && bet_ptr->get_odds()==0) {
          switch (bet_ptr->get_point()) {
            case  4 :
            case 10 :
              payoff+=bet_ptr->player_action(roll,marker,3*bet_ptr->get_bet());
              break;
            case 5 :
            case 9 :
              payoff+=bet_ptr->player_action(roll,marker,4*bet_ptr->get_bet());
              break;
            case 6 :
            case 8 :
              payoff+=bet_ptr->player_action(roll,marker,5*bet_ptr->get_bet());
              break;
            default :
              break;
          }    
        }   
      }
      bets.push_back(new come_bet(n,5));
      payoff += payoff_t(0, -5);
      return payoff;
    }
    else {
      return payoff_t(0,0);
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }

  payoff_t pass_line_with_craps_check_and_odds::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
      list<bet_base*>::iterator bets_itr = bets.begin();
      while(bets_itr != bets.end()) {
        bet_base* bet_ptr = *bets_itr++;
        if (bet_ptr->get_name()=="pass_line_bet" && bet_ptr->get_odds()==0) {
          switch (marker.point) {
            case  4 :
            case 10 :
              return bet_ptr->player_action(roll,marker,3*bet_ptr->get_bet());
              break;
            case 5 :
            case 9 :
              return bet_ptr->player_action(roll,marker,4*bet_ptr->get_bet());
              break;
            case 6 :
            case 8 :
              return bet_ptr->player_action(roll,marker,5*bet_ptr->get_bet());
              break;
            default :
              return payoff_t(0, 0);
              break;
          }    
        }   
        else {
          return payoff_t(0, 0);
        }
      }
    }
    else {
      bets.push_back(new pass_line_bet(n,5));
      payoff_t payoff = payoff_t(0, -5);
      bets.push_back(new any_craps_bet(n,1));
      payoff += payoff_t(0, -1);
      return payoff;
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }

  payoff_t come_bet_with_craps_check_and_odds::operator()
    (roll_t roll, marker_t marker, INTEGER n, std::list<bet_base*>& bets)
  {
    if (marker.on) {
      payoff_t payoff(0, 0);
      list<bet_base*>::iterator bets_itr = bets.begin();
      while(bets_itr != bets.end()) {
        bet_base* bet_ptr = *bets_itr++;
        if (bet_ptr->get_name()=="come_bet" && bet_ptr->get_odds()==0) {
          switch (bet_ptr->get_point()) {
            case  4 :
            case 10 :
              payoff+=bet_ptr->player_action(roll,marker,3*bet_ptr->get_bet());
              break;
            case 5 :
            case 9 :
              payoff+=bet_ptr->player_action(roll,marker,4*bet_ptr->get_bet());
              break;
            case 6 :
            case 8 :
              payoff+=bet_ptr->player_action(roll,marker,5*bet_ptr->get_bet());
              break;
            default :
              break;
          }    
        }   
      }
      bets.push_back(new come_bet(n,5));
      payoff += payoff_t(0, -5);
      bets.push_back(new any_craps_bet(n,1));
      payoff += payoff_t(0, -1);
      return payoff;
    }
    else {
      return payoff_t(0,0);
    }
    error("Error, " + get_name() + "::operator(), should never happen");
    return payoff_t(0,0);
  }

}
