#include "sudoku.h"

/* if a cell has X, other cells in same row/col/box cannot have X */

static int CT_VALS_ON = 0;

FUNC turn_val_on(int x,int y,int val)		// x,y - cell coords; val - 1 to 9
{
int xx, yy, vval;

//char code[10]; 
//bot_get_cell_code(0,7,code); printf("funny string 1 is %s\n", code);
//printf ("SETTING (%d,%d) to %d\n", x, y, val);

for (xx = 0; xx < 9; xx++)
    bot_set_val_code(xx, y, val, VAL_NO);	// set the col to off
for (yy = 0; yy < 9; yy++)
    bot_set_val_code(x, yy, val, VAL_NO);	// set the row to off
for (vval = 1; vval <= 9; vval++)		
    bot_set_val_code(x, y, vval, VAL_NO);	// set the cell to off

bot_set_box_off((x/3) * 3, (y/3) * 3, val);	
bot_set_val_code(x, y, val, VAL_YES);	
CT_VALS_ON++;
}
 
FUNC int ct_turned_on()
{
return CT_VALS_ON;
}

/* if all other cells in given row/col/box do not have X, this one must */

FUNC int check_val_to_turn_on(int x,int y,int val)
{
char code;

bot_get_val_code(x,y,val,&code);
if (code != VAL_MAYBE)
    return NO;
if (others_in_row_are_off(x,y,val))	
    return ONLY_VAL_IN_ROW;
else if (others_in_col_are_off(x,y,val))	
    return ONLY_VAL_IN_COL;
else if (other_vals_in_cell_are_off(x,y,val))	
    return ONLY_VAL_IN_CELL;
else 
    return NO;
}

FUNC bool val_is_set_in_box(int box, int val)
{
int x,y,ii,jj;

get_box_coords(box,&x,&y);
for (ii = 0; ii < 3; ii++)
    for (jj = 0; jj < 3; jj++)
       if (bot_get_cell_val(x+ii,y+jj) == val)
           return 1;
return 0;
}

FUNC bool box_set_rowcol_off(int box, int num, int val, int rowcol)
{
int x,y;

get_box_coords(box,&x,&y);
return (rowcol == ROW) ? set_box_row_off(x+num, y, val) : set_box_col_off(x, y+num, val);
}

FUNC bool box_rowcol_has_maybes(int box, int num, int val, int rowcol, int *p_num)
{
int x,y, ret;

get_box_coords(box,&x,&y);
ret = (rowcol == ROW) ? box_row_is_off(x+num, y, val) : box_col_is_off(x, y+num, val);
if (ret)
    return 0;		// rowcol has all NOs

*p_num = num; 		// num of rowcol that has MAYBE
return 1;    
}

FUNC bool box_row_is_off(int x, int ylow, int val) 
{
char code1, code2, code3;

//printf("In box_row_is_off(%d,%d,%d\n", x, ylow, val);
bot_get_val_code(x, ylow, val, &code1);
bot_get_val_code(x, ylow+1, val, &code2);
bot_get_val_code(x, ylow+2, val, &code3);
//printf("Codes are %c %c %c\n", code1, code2, code3);
return (code1 == VAL_NO && code2 == VAL_NO && code3 == VAL_NO);
}

FUNC set_box_row_off(int x, int ylow, int val) 
{
bot_set_val_code(x, ylow, val, VAL_NO);
bot_set_val_code(x, ylow+1, val, VAL_NO);
bot_set_val_code(x, ylow+2, val, VAL_NO);
}

FUNC set_box_col_off(int xlow, int y, int val) 
{
bot_set_val_code(xlow, y, val, VAL_NO);
bot_set_val_code(xlow+1, y, val, VAL_NO);
bot_set_val_code(xlow+2, y, val, VAL_NO);
}

FUNC bool box_col_is_off(int xlow,int y,int val) 
{
char code1, code2, code3;

bot_get_val_code(xlow, y, val, &code1);
bot_get_val_code(xlow+1, y, val, &code2);
bot_get_val_code(xlow+2, y, val, &code3);
return (code1 == VAL_NO && code2 == VAL_NO && code3 == VAL_NO);
}

FUNC bot_get_other_boxes_in_rowcol(int box, int rowcol, int *p_b1, int *p_b2)
{
int num, num1, num2, incr;

num = (rowcol == ROW) ? box % 3 : box / 3;
if (num == 0) 
    {num1 = 1; num2 = 2;}
else if (num == 1) 
    {num1 = -1; num2 = 1;}
else               
    {num1 = -2; num2 = -1;}

incr = (rowcol == ROW) ? 1 : 3;
*p_b1 = box + num1 * incr;
*p_b2 = box + num2 * incr;
// printf("For box %d, nums are %d (%d,%d); incr is %d. Other boxes in %s are %d and %d\n", 
// box, num, num1, num2, incr, (rowcol == ROW) ? "row" : "col", *p_b1, *p_b2); 
}
