//Create the MAIN array arrayMain[j][k]
arrayMain = new Array(10);
for (var j = 1; j <= 9; j++){
   arrayMain[j] = new Array(10);
}

//Create the POSSIBLE array arrayPossible[j][k]
arrayPossible = new Array(10);
for (var j = 1; j <= 9; j++){
   arrayPossible[j] = new Array(10);
}

function AnalyserMain(jRow,kColumn){
   //Check each cell on same ROW, COLUMN and SQUARE to find POSSIBLE values

   //Leave if empty
   if(arrayMain[jRow][kColumn] == '')return;

   //Set as default value if cell contains something
   arrayPossible[jRow][kColumn] = '_________'

   //ROW check
   for (var k = 1; k <= 9; k++){
      if(arrayMain[jRow][k] == ''){
         //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
         //Remove current value from list of possible values
         arrayPossible[jRow][k] = StringReplacer(arrayPossible[jRow][k],arrayMain[jRow][kColumn]);
      }
   }

   //COLUMN check
   for (var k = 1; k <= 9; k++){
      if(arrayMain[k][kColumn] == ''){
         //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
         //Remove current value from list of possible values
         arrayPossible[k][kColumn] = StringReplacer(arrayPossible[k][kColumn],arrayMain[jRow][kColumn]);
      }
   }

   //MAJOR SQUARE check
   var rowFrom;
   var rowTo;
   var colFrom;
   var colTo;

   //Find the MAJOR SQUARE where cell is located
   var square = FindSquare(jRow,kColumn);
   //alert(square);
   switch(square){
      case 1:
        rowFrom =1;
        rowTo   =3;
        colFrom =1;
        colTo   =3;
        break;
      case 2 :
        rowFrom =1;
        rowTo   =3;
        colFrom =4;
        colTo   =6;
        break;
      case 3:
        rowFrom =1;
        rowTo   =3;
        colFrom =7;
        colTo   =9;
        break;
      case 4:
        rowFrom =4;
        rowTo   =6;
        colFrom =1;
        colTo   =3;
        break;
      case 5:
        rowFrom =4;
        rowTo   =6;
        colFrom =4;
        colTo   =6;
        break;
      case 6:
        rowFrom =4;
        rowTo   =6;
        colFrom =7;
        colTo   =9;
        break;
      case 7:
        rowFrom =7;
        rowTo   =9;
        colFrom =1;
        colTo   =3;
        break;
      case 8:
        rowFrom =7;
        rowTo   =9;
        colFrom =4;
        colTo   =6;
        break;
      case 9:
        rowFrom =7;
        rowTo   =9;
        colFrom =7;
        colTo   =9;
        break;

   }
   for (var m = rowFrom; m <= rowTo; m++){
      for (var n = colFrom; n <= colTo; n++){
         if(arrayMain[m][n] == ''){
            //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
            //Remove current value from list of possible values
            arrayPossible[m][n] = StringReplacer(arrayPossible[m][n],arrayMain[jRow][kColumn]);
         }
      }
   }
}

function AnalyserOneTwoThree(){
   /*Check for ONE, TWO or THREE empty cells in EVERY major square on the same ROW/COLUMN
   //If values MUST be say, "368" then rest of Row/Column CANNOT contain "368"
   j = ROW/COLUMN number - we start from Top Row/Left Column
   k = Number of COMBINATION
   m = Column/Row number
   rc = 1 ==> ROWS
   rc = 2 ==> COLUMNS   */

   for (var rc = 1; rc <= 2; rc++){
      for (var j = 1; j <= 9; j++){
         for (var k = 1; k <= 3; k++){
            //Analyse each ROW (there are THREE major squares on each row so k goes from 1 to 3)
            switch(k){
               case 1:
                 From =1;
                 To   =3;
                 break;
               case 2 :
                 From =4;
                 To   =6;
                 break;
               case 3:
                 From =7;
                 To   =9;
                 break;
            }

            //d is a DIGIT in the POSSIBLE ARRAY (ie arrayPossible[][] )
            for (var d = 1; d <= 9; d++){
               var counter = 0;
               for (var m = From; m <= To; m++){
                  //See if there is a DIGIT "d" which appears in ONE, TWO or THREE Cells of "arrayPossible[j][m]"
                  if(rc==1){
                     if(arrayPossible[j][m].indexOf(d) >= 0 ){
                     counter = counter + 1;
                     }
                     if((counter >= 1 && counter <= 3) && DigitElsewhereInSquare(j,m,d,rc) == false){
                        DigitRemover(j,m,d,rc);
                     }
                  }
                  if(rc==2){
                     if(arrayPossible[m][j].indexOf(d) >= 0 ){
                     counter = counter + 1;
                     }
                     if((counter >= 1 && counter <= 3) && DigitElsewhereInSquare(m,j,d,rc) == false){
                        DigitRemover(m,j,d,rc);
                     }
                  }
               }
            }
         }
      }
   }
}

function ArrayToEntries(){
   //Put values held in Main Array onto the form
   var temp;
   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         switch(j){
            case 1:
              temp = 'A';
              break;
            case 2 :
              temp = 'B';
              break;
            case 3:
              temp = 'C';
              break;
            case 4:
              temp = 'D';
              break;
            case 5:
              temp = 'E';
              break;
            case 6:
              temp = 'F';
              break;
            case 7:
              temp = 'G';
              break;
            case 8:
              temp = 'H';
              break;
            case 9:
              temp = 'I';
              break;
         }
         //if(arrayMain[j][k] != '')alert('j = ' + j + '  k = ' + k + '  arrayMain[j][k] = ' + arrayMain[j][k]);
         temp = temp + k;
         eval('document.possible.' + temp + '.value = ' + 'arrayMain[j][k]');
      }
   }
}

function ArrayToPossible(){
   //Put values held in the Possible Array onto the form ( in BLACK)
   var fonter = '<font color="#000000" size="1" face="verdana, arial">';
   var temp;

   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         switch(j){
            case 1:
              temp = 'A';
              break;
            case 2 :
              temp = 'B';
              break;
            case 3:
              temp = 'C';
              break;
            case 4:
              temp = 'D';
              break;
            case 5:
              temp = 'E';
              break;
            case 6:
              temp = 'F';
              break;
            case 7:
              temp = 'G';
              break;
            case 8:
              temp = 'H';
              break;
            case 9:
              temp = 'I';
              break;
         }
         //if(arrayName[j][k] != '')alert('j = ' + j + '  k = ' + k + '  arrayName[j][k] = ' + arrayName[j][k]);
         temp = temp + k + 'p';
         document.getElementById(temp).innerHTML = fonter + arrayPossible[j][k] + '</font>';
      }
   }
}

function Boss(jRow,kRow,value){
   //This is activated whenever user inputs an entry

   EntriesToArray();
   Vet();
   VetConflict(jRow,kRow);

   Starter();

   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         AnalyserMain(j,k);
      }
   }
   AnalyserOneTwoThree();
   ArrayToEntries();
   ArrayToPossible();
   FindSingletons();
   FindSingles();
}

function ColourPossibles(jRow, kCol, strDigit, intColour){
   //Highlight possible values in color
   //alert('In ColourPossibles option 0 ' + document.possible.options[0].checked);
   //alert('In ColourPossibles option 1  ' + document.possible.options[1].checked);

   var fonter = '<font color="#000000" size="1" face="verdana, arial">';
   var fontColoured;
   var temp;

   switch(intColour){
      case 1:                  //RED
        fontColoured = '<font color="#FF0000" size="2" face="verdana, arial">';
        break;
      case 2 :                    //GREEN
        fontColoured = '<font color="#700000" size="2" face="verdana, arial">';
        break;
      case 3:                     //BLUE
        fontColoured = '<font color="#0000FF" size="2" face="verdana, arial">';
        break;
   }

   //All RED at the moment but CAN have different colours using code above
   fontColoured = '<font color="#FF0000" size="2" face="verdana, arial">';

   var len = arrayPossible[jRow][kCol].length;
   var pos = arrayPossible[jRow][kCol].indexOf(strDigit);
   var front = arrayPossible[jRow][kCol].slice(0,pos);
   var back = arrayPossible[jRow][kCol].slice(pos + 1,len);
   //alert('  len = ' + len + '  pos = ' + pos + '  front = ' + front + '  back = ' + back);

   switch(jRow){
      case 1:
        temp = 'A';
        break;
      case 2 :
        temp = 'B';
        break;
      case 3:
        temp = 'C';
        break;
      case 4:
        temp = 'D';
        break;
      case 5:
        temp = 'E';
        break;
      case 6:
        temp = 'F';
        break;
      case 7:
        temp = 'G';
        break;
      case 8:
        temp = 'H';
        break;
      case 9:
        temp = 'I';
        break;
   }

   temp = temp + kCol;
   //alert('temp = ' + temp);
   document.getElementById(temp + 'p').innerHTML = fonter + front + '</font>' + fontColoured + '<b>' + strDigit + '</b></font>' + fonter + back + '</font>';

}

function DigitElsewhereInSquare(j,m,d,rc){
   //Is this digit possible elsewhere in this major square?
   //Find the SQUARE from Row = j and Col = m
   var s = FindSquare(j,m);

   var rowFrom;
   var rowTo;
   var colFrom;
   var colTo;
   switch(s){
      case 1:
         rowFrom =1;
         rowTo   =3;
         colFrom =1;
         colTo   =3;
         break;
      case 2 :
         rowFrom =1;
         rowTo   =3;
         colFrom =4;
         colTo   =6;
         break;
      case 3:
         rowFrom =1;
         rowTo   =3;
         colFrom =7;
         colTo   =9;
         break;
      case 4:
         rowFrom =4;
         rowTo   =6;
         colFrom =1;
         colTo   =3;
         break;
      case 5:
         rowFrom =4;
         rowTo   =6;
         colFrom =4;
         colTo   =6;
         break;
      case 6:
         rowFrom =4;
         rowTo   =6;
         colFrom =7;
         colTo   =9;
         break;
      case 7:
         rowFrom =7;
         rowTo   =9;
         colFrom =1;
         colTo   =3;
         break;
      case 8:
         rowFrom =7;
         rowTo   =9;
         colFrom =4;
         colTo   =6;
         break;
      case 9:
         rowFrom =7;
         rowTo   =9;
         colFrom =7;
         colTo   =9;
         break;
    }

    //alert(' rowFrom = ' + rowFrom + ' rowTo = ' + rowTo + ' colFrom = ' + colFrom + ' colTo = ' + colTo);
    if(rc==1){         //ROWS
       for (var p = rowFrom; p <= rowTo; p++){
          for (var q = colFrom; q <= colTo; q++){
            if(p != j && arrayPossible[p][q].indexOf(d) >= 0){
               //alert('In DigitElsewhereInSquare(j,m,d,rc)' + '  j = ' + j  + '  m = ' + m  + '  d = ' + d  + '  p = ' + p + ' q = ' + q);
               return true;
            }
          }
       }
    }
    if(rc==2){        //COLUMNS
       for (var q = colFrom; q <= colTo; q++){
          for (var p = rowFrom; p <= rowTo; p++){
            if(q != m && arrayPossible[p][q].indexOf(d) >= 0){
               //alert('In DigitElsewhereInSquare(j,m,d,rc)' + '  j = ' + j  + '  m = ' + m  + '  d = ' + d  + '  p = ' + p + ' q = ' + q);
               return true;
            }
          }
       }
    }
    //alert('return false');
    return false;
}

function DigitRemover(j,m,d,rc){
   //Remove single digit from Row/Column

   //alert('In DigitRemover' + '  j = ' + j  + '  m = ' + m  + '  d = ' + d );

   //Find the SQUARE from Row/Col = j and Col/Row = m
   var sKeep = FindSquare(j,m);

   for (var k = 1; k <= 9; k++){
      if(rc==1){          //ROWS
         if(sKeep != FindSquare(j,k)){
            arrayPossible[j][k] = StringReplacer(arrayPossible[j][k],d);
         }
      }
      if(rc==2){          //COLUMNS
         if(sKeep != FindSquare(k,m)){
            arrayPossible[k][m] = StringReplacer(arrayPossible[k][m],d);
         }
      }
   }
}

function EntriesToArray(){
   //Take user entries and store them in the Main Array
   var temp;
   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         switch(j){
            case 1:
              temp = 'A';
              break;
            case 2 :
              temp = 'B';
              break;
            case 3:
              temp = 'C';
              break;
            case 4:
              temp = 'D';
              break;
            case 5:
              temp = 'E';
              break;
            case 6:
              temp = 'F';
              break;
            case 7:
              temp = 'G';
              break;
            case 8:
              temp = 'H';
              break;
            case 9:
              temp = 'I';
              break;
         }
         //if(arrayMain[j][k] != '')alert('j = ' + j + '  k = ' + k + '  arrayMain[j][k] = ' + arrayMain[j][k]);
         temp = temp + k ;
         arrayMain[j][k] = eval('document.possible.' + temp + '.value');
      }
   }
}

function FindSingles(){
   //Check each cell to find cells which can only have ONE value and highlight them

   var counter = 0;

   //Row check for each ROW, COLUMN and SQUARE is j
   for (var j = 1; j <= 9; j++){

      //ROW Check
      //d is 1, 2, 3 ....... 9
      for (var d = 1; d <= 9; d++){
         //For each CELL in ROW j is k
         for (var k = 1; k <= 9; k++){
            if(arrayPossible[j][k].indexOf(d) >= 0){
               counter = counter + 1;
               var kRem = k;
            }
         }
         //if(counter == 1)alert('ROW analysis: Put a ' +  d + ' in row ' + j + ', col ' + kRem);
         if(counter == 1)ColourPossibles(j, kRem, d, 1);
         counter = 0;
      }

      //COLUMN Check
      counter = 0;
      //d is 1, 2, 3 ....... 9
      for (var d = 1; d <= 9; d++){
         //For each CELL in COL k is j
         for (var k = 1; k <= 9; k++){
            if(arrayPossible[k][j].indexOf(d) >= 0){
               counter = counter + 1;
               var kRem = k;
            }
         }
         //if(counter == 1)alert('ROW analysis: Put a ' +  d + ' in row ' + kRem + ', col ' + j);
         if(counter == 1)ColourPossibles(kRem, j , d, 2);
         counter = 0;
      }

      //SQUARE check
      counter = 0;
      var rowFrom;
      var rowTo;
      var colFrom;
      var colTo;

      //Go round each MAJOR SQUARE
      //alert(j);
      switch(j){
         case 1:
           rowFrom =1;
           rowTo   =3;
           colFrom =1;
           colTo   =3;
           break;
         case 2 :
           rowFrom =1;
           rowTo   =3;
           colFrom =4;
           colTo   =6;
           break;
         case 3:
           rowFrom =1;
           rowTo   =3;
           colFrom =7;
           colTo   =9;
           break;
         case 4:
           rowFrom =4;
           rowTo   =6;
           colFrom =1;
           colTo   =3;
           break;
         case 5:
           rowFrom =4;
           rowTo   =6;
           colFrom =4;
           colTo   =6;
           break;
         case 6:
           rowFrom =4;
           rowTo   =6;
           colFrom =7;
           colTo   =9;
           break;
         case 7:
           rowFrom =7;
           rowTo   =9;
           colFrom =1;
           colTo   =3;
           break;
         case 8:
           rowFrom =7;
           rowTo   =9;
           colFrom =4;
           colTo   =6;
           break;
         case 9:
           rowFrom =7;
           rowTo   =9;
           colFrom =7;
           colTo   =9;
           break;
      }

      //alert(' rowFrom = ' + rowFrom + ' rowTo = ' + rowTo + ' colFrom = ' + colFrom + ' colTo = ' + colTo);
      //d is 1, 2, 3 ....... 9
      for (var d = 1; d <= 9; d++){
         for (var m = rowFrom; m <= rowTo; m++){
            for (var n = colFrom; n <= colTo; n++){
               if(arrayPossible[m][n].indexOf(d) >= 0){
                  counter = counter + 1;
                  var mRem = m;
                  var nRem = n;
               }
            }
         }
         //if(counter == 1)alert('SQUARE analysis: Put a ' +  d + ' in row ' + mRem + ', col ' + nRem);
         if(counter == 1)ColourPossibles(mRem, nRem, d, 3);
         counter = 0;
      }
   }
}

function FindSingletons(){
   //Check each cell SINGLE entries
   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         //For 1, 2, 3 ....... 9 is d
         var counter = 0;
         for (var d = 1; d <= 9; d++){
            if(arrayPossible[j][k].indexOf(d) >= 0){
               counter = counter + 1;
               var kRem = k;
               var dRem = d;
            }
         }
         //if(counter == 1)alert('SINGLETON analysis: Put a ' +  dRem + ' in row ' + j + ', col ' + kRem);
         if(counter == 1)ColourPossibles(j, kRem, dRem, 1);
      }
   }
}

function FindSquare(jRow,kColumn){
   /*Find the MAJOR SQUARE where cell is located
   =========================================
   ||   |   |   ||   |   |   ||   |   |   ||
   -----------------------------------------
   ||   | 1 |   ||   | 2 |   ||   | 3 |   ||
   -----------------------------------------
   ||   |   |   ||   |   |   ||   |   |   ||
   =========================================
   ||   |   |   ||   |   |   ||   |   |   ||
   -----------------------------------------
   ||   | 4 |   ||   | 5 |   ||   | 6 |   ||
   -----------------------------------------
   ||   |   |   ||   |   |   ||   |   |   ||
   =========================================
   ||   |   |   ||   |   |   ||   |   |   ||
   -----------------------------------------
   ||   | 7 |   ||   | 8 |   ||   | 9 |   ||
   -----------------------------------------
   ||   |   |   ||   |   |   ||   |   |   ||
   =========================================
   */

   if(jRow >= 1 && jRow <= 3) {
      if(kColumn >= 1 && kColumn <= 3)return 1;
      if(kColumn >= 4 && kColumn <= 6)return 2;
      if(kColumn >= 7 && kColumn <= 9)return 3;
   }
   if(jRow >= 4 && jRow <= 6) {
      if(kColumn >= 1 && kColumn <= 3)return 4;
      if(kColumn >= 4 && kColumn <= 6)return 5;
      if(kColumn >= 7 && kColumn <= 9)return 6;
   }
   if(jRow >= 7 && jRow <= 9) {
      if(kColumn >= 1 && kColumn <= 3)return 7;
      if(kColumn >= 4 && kColumn <= 6)return 8;
      if(kColumn >= 7 && kColumn <= 9)return 9;
   }
}

function Resetter(){
   document.possible.reset(document.possible);
   //alert('Reset pressed');
   Starter();
   document.possible.A1.focus();
}

function Starter(){
   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         arrayPossible[j][k] = '123456789';
      }
   }
   ArrayToPossible();
}

function StringReplacer(sample,remover){
   return sample.replace(remover,'_');
}

function Vet(){
   for (var j = 1; j <= 9; j++){
      for (var k = 1; k <= 9; k++){
         var du = '' + arrayMain[j][k];
         if((du != '') && (du != '1') && (du != '2') && (du != '3') && (du != '4') && (du != '5') && (du != '6') && (du != '7') && (du != '8') && (du != '9')){
            alert('Entry MUST be Blank, 1, 2, 3, 4, 5, 6, 7, 8 or 9 ONLY');
            arrayMain[j][k] = ''
         }
      }
   }
}

function VetConflict(jRow,kColumn){
   //Check each single squre for conflicts

   //Leave if empty
   if(arrayMain[jRow][kColumn] == '')return;

   var duplicate = 'no';

   //Row check
   for (var k = 1; k <= 9; k++){
      if((arrayMain[jRow][kColumn] == arrayMain[jRow][k]) && (k != kColumn)){
         //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
         alert('Identical ROW entry already exists - new entry will be deleted');
         duplicate = 'yes';
         break;
      }
   }

   //Column check
   for (var k = 1; k <= 9; k++){
      if((arrayMain[jRow][kColumn] == arrayMain[k][kColumn]) && (k != jRow)){
         //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
         alert('Identical COLUMN entry already exists - new entry will be deleted');
         duplicate = 'yes';
         break;
      }
   }

   //Square check
   var rowFrom;
   var rowTo;
   var colFrom;
   var colTo;

   //Find the MAJOR SQUARE where cell is located
   var square = FindSquare(jRow,kColumn);
   //alert(square);
   switch(square){
      case 1:
        rowFrom =1;
        rowTo   =3;
        colFrom =1;
        colTo   =3;
        break;
      case 2 :
        rowFrom =1;
        rowTo   =3;
        colFrom =4;
        colTo   =6;
        break;
      case 3:
        rowFrom =1;
        rowTo   =3;
        colFrom =7;
        colTo   =8;
        break;
      case 4:
        rowFrom =4;
        rowTo   =6;
        colFrom =1;
        colTo   =3;
        break;
      case 5:
        rowFrom =4;
        rowTo   =6;
        colFrom =4;
        colTo   =6;
        break;
      case 6:
        rowFrom =4;
        rowTo   =6;
        colFrom =7;
        colTo   =9;
        break;
      case 7:
        rowFrom =7;
        rowTo   =9;
        colFrom =1;
        colTo   =3;
        break;
      case 8:
        rowFrom =7;
        rowTo   =9;
        colFrom =4;
        colTo   =6;
        break;
      case 9:
        rowFrom =7;
        rowTo   =9;
        colFrom =7;
        colTo   =9;
        break;

   }

   //alert('rowFrom = ' + rowFrom +  '  rowTo = ' + rowTo + '  colFrom = ' + colFrom + '  colTo = ' + colTo);

   for (var m = rowFrom; m <= rowTo; m++){
      for (var n = colFrom; n <= colTo; n++){
         if((arrayMain[jRow][kColumn] == arrayMain[m][n]) && (m != jRow) && (n != kColumn)){
            //alert('jRow = ' + jRow + '  kColumn = ' +  kColumn + '  k = ' + k);
            alert('Identical SQUARE entry already exists - new entry will be deleted');
            duplicate = 'yes';
            break;
         }
      }
   }

   if(duplicate == 'yes')arrayMain[jRow][kColumn] = '';

}

