//
// © 2005-2007 Cazfi
//

#ifndef H_SDKS
#define H_SDKS

#define SDKS_VERSION "0.4.0"

enum remove_result { RR_KNOWN, RR_ADVANCE, RR_SOLVED };
enum construct_type { CT_ROW, CT_COL, CT_REG };

const int MIN_BASE = 2;
const int MAX_BASE = 5;

class cell
{
 public:
  cell();
  cell(int base);
  ~cell();
  void print();
  bool set_result(int result_in, const char *reason);
  remove_result remove_possibility(int removed, const char *reason);
  int solved();
  bool is_possible(int result_in);
  void setxy(int x_in, int y_in);
  int get_x();
  int get_y();
 private:
  int result;
  int possibility_count;
  bool *possibilities;
  int x;
  int y;
  int base_size;
};


class sudoku
{
 public:
  sudoku();
  sudoku(int base);
  ~sudoku();
  void print();
  void print_possibilities();
  bool read();
  bool solve();
  bool check_legality();
 private:
  bool solve_base(construct_type construct, int cnum);
  bool solve_slow_rowcol(construct_type construct, int row);
  bool solve_region_slow(int region);
  bool solve_pairing(construct_type construct, int cnum);
  cell *get_cell(construct_type construct, int cnum, int index);
  int get_reg(construct_type construct, int cnum, int index);
  cell *get_row_cell(int row, int index);
  cell *get_col_cell(int col, int index);
  cell *get_reg_cell(int reg, int index);
  cell *get_regxy_cell(int reg, int x, int y);
  int region_origo_x(int region);
  int region_origo_y(int region);
  int linear_to_x(int region, int linear);
  int linear_to_y(int region, int linear);
  bool region_x(int region, int x);
  bool region_y(int region, int y);
  const char *construct_name(construct_type construct);
  int char_to_int(char c);
  char int_to_char(int n);
  void print_possibility_ruler(); // Horizontal ruler
  void print_possibility_verticals();
  cell ***cells;
  int unsolved;
  int base_size;
  int dimension;
};


#endif // H_SDKS
