import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

import java.util.List;

import CLIPSJNI.*;

public class SdkServlet extends HttpServlet {
   public void doPost( HttpServletRequest request, HttpServletResponse response )
      throws ServletException, IOException
   {
      response.setContentType( "text/html" );

      String root = getInitParameter("root");      // root defined in zone.properties

      PrintWriter out = response.getWriter();

      out.println("<html>");
      out.println("<meta http-equiv=\"Content-Type\" content=\"text/html\" >");
      out.println("<head><title>Sudoku Solver</title></head>");
      out.println("<body bgcolor=\"#D3D3D3\" text=\"#000000\" link=\"#800000\" vlink=\"#666633\" alink=\"#1445A1\">");
      out.println("<center><font face=\"Courier New\" size=\"6\"><b>Sudoku Solver</b></font></center>");
      out.println("<p><div align=\"center\"><center>");

      System.load("c:/clips/CLIPSJNI/CLIPSJNI.dll");

      Environment clips = new Environment();
      clips.load(root + "/sylee/courses/clips/clipsjni/examples/sudoku/sudoku.clp");
      clips.load(root + "/sylee/courses/clips/clipsjni/examples/sudoku/solve.clp");

      clips.reset();
      clips.assertString("(phase expand-any)");
      clips.assertString("(size 3)");

      // read input from web page
      String data = request.getParameter("data");
      StringBuffer cb = new StringBuffer(data);
      StringBuffer input = new StringBuffer();
      for (int i=0; i<cb.length(); i++) {
        char c = cb.charAt(i);                      // strip-off white spaces
        if (!Character.isWhitespace(c)) input.append(c);
      }

      for (int i=0; i<input.length(); i++) {
        int id = i+1;
        int row = i / 9;
        int col = i % 9;
        int group = row / 3 * 3 + col / 3;
        char ch = input.charAt(i);
        if (Character.isDigit(ch)) {
            int v = Character.digit(ch, 10);
            String s1 = "(possible (row " + row + ")(column " + col
                       + ")(value " + v + ")(group " + group + ")(id " + id + "))";
            clips.assertString(s1);
        } else {
            String s2 = "(possible (row " + row + ")(column " + col
                        + ")(value any)(group " + group + ")(id " + id + "))";
            clips.assertString(s2);
        }
      }

      clips.run();

      // retrieve result from clipsjni
      String evalStr = "(find-all-facts ((?f possible)) TRUE)";
      MultifieldValue pv = (MultifieldValue) clips.eval(evalStr);
      int tNum = pv.listValue().size();
      if (tNum == 0) return;
      List theList = pv.listValue();
      FactAddressValue fv;
      int id, value;
      int[] digits = new int[81];
      for (int i=0; i<81; i++) digits[i]=0;

      for (int i=0; i<tNum; i++)
        {
         fv = (FactAddressValue) pv.listValue().get(i);
         id = Integer.parseInt(fv.getFactSlot("id").toString());
         StringBuffer sb = new StringBuffer(fv.getFactSlot("value").toString());
         if (Character.isDigit(sb.charAt(0)))
                digits[id-1] = Integer.parseInt(sb.toString());
        }

      // print output web page
      out.println("<table border=\"2\" cellpadding=\"0\" cellspacing=\"0\" bgcolor=\"#CCE6FF\" bordercolor=\"#66B3FF\" width=\"60%\" height=\"80%\">");
      for (int i=0; i<digits.length; i++) {
         if (i % 9 == 0) out.println("<tr>");
         if (digits[i]!=0)
            out.println("<td width=\"11%\" height=\"11%\"><p align=\"center\">
                <b><font size=6 face=\"Courier New\">" + digits[i] + "</font></b></td>");
         else
            out.println("<td width=\"11%\" height=\"11%\">&nbsp;</td>");
         if (i % 9 == 8) out.println("</tr>");
        }

    out.println("</table>");
    out.println("</center></div></body></html>");
    out.close();
    }
}
