package puzzle;

import module java.base;
import puzzle.SwedishGenerator.Grid;
import puzzle.SwedishGenerator.Lemma;
import puzzle.SwedishGenerator.Slotinfo;
import static java.lang.Long.bitCount;
import static java.lang.Long.numberOfTrailingZeros;
public class GridBuilder {
   
   public static boolean placeWord(final Grid grid, final byte[] g, final int key, final long lo, final long hi, final long w) {
      final long glo = grid.lo, ghi = grid.hi;
      if (Slotinfo.increasing(key)) {
         for (long b = lo & glo; b != SwedishGenerator.X; b &= b - 1) {
            int idx = numberOfTrailingZeros(b);
            if (g[idx] != Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)))) return false;
         }
         int bcLo = bitCount(lo);
         for (long b = hi & ghi; b != SwedishGenerator.X; b &= b - 1) {
            int idx = numberOfTrailingZeros(b);
            if (g[64 | idx] != Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)))) return false;
         }
         
         long maskLo = lo & ~glo, maskHi = hi & ~ghi;
         if ((maskLo | maskHi) != SwedishGenerator.X) {
            for (long b = maskLo; b != SwedishGenerator.X; b &= b - 1) {
               int idx = numberOfTrailingZeros(b);
               g[idx] = Lemma.byteAt(w, bitCount(lo & ((1L << idx) - 1)));
            }
            for (long b = maskHi; b != SwedishGenerator.X; b &= b - 1) {
               int idx = numberOfTrailingZeros(b);
               g[64 | idx] = Lemma.byteAt(w, bcLo + bitCount(hi & ((1L << idx) - 1)));
            }
            grid.lo |= maskLo;
            grid.hi |= maskHi;
         }
      } else {
         int bcHi = bitCount(hi);
         for (long b = hi & ghi; b != SwedishGenerator.X; b &= b - 1) {
            int idx = numberOfTrailingZeros(b);
            if (g[64 | idx] != Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))))) return false;
         }
         for (long b = lo & glo; b != SwedishGenerator.X; b &= b - 1) {
            int idx = numberOfTrailingZeros(b);
            if (g[idx] != Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))))) return false;
         }
         
         long maskLo = lo & ~glo, maskHi = hi & ~ghi;
         if ((maskLo | maskHi) != SwedishGenerator.X) {
            for (long b = maskHi; b != SwedishGenerator.X; b &= b - 1) {
               int idx = numberOfTrailingZeros(b);
               g[64 | idx] = Lemma.byteAt(w, bitCount(hi & ~((1L << idx) | ((1L << idx) - 1))));
            }
            for (long b = maskLo; b != SwedishGenerator.X; b &= b - 1) {
               int idx = numberOfTrailingZeros(b);
               g[idx] = Lemma.byteAt(w, bcHi + bitCount(lo & ~((1L << idx) | ((1L << idx) - 1))));
            }
            grid.lo |= maskLo;
            grid.hi |= maskHi;
         }
      }
      return true;
   }
}
