/* 
 * Pescetti Pseudo-Duplimate Generator
 * 
 * Copyright (C) 2007 Matthew Johnson
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License Version 2 as published by
 * the Free Software Foundation.  This program is distributed in the hope that
 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.  You should have received a
 * copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *
 * To Contact me, please email src@matthew.ath.cx
 *
 */
package cx.ath.matthew.pescetti;

import cx.ath.matthew.debug.Debug;

import java.io.PrintStream;
import java.text.DecimalFormat;

public class HTMLPrinter extends Printer implements Constants
{
   private PrintStream out;
   private boolean infulltable = false;
   private boolean inrow = false;
   private boolean incell = false;
   private boolean inback = false;
   private int cellcount = 0;
   private int rowcount = 0;
   private int permcount = 0;
   private static final int MAXCELLS = 4;
   public HTMLPrinter(PrintStream out, String header)
   {
      this.out = out;
      out.println("<!DOCTYPE HTML SYSTEM>");
      out.println("<html><head><title>"+header+"</title>");
      out.println("<meta http-equiv='Content-Type' content='text/html;charset=utf-8' />");
      out.println("<style type='text/css'>");
      out.println("<!--");
      out.println("table, td, tr {");
      out.println("   padding: 0px;");
      out.println("   margin: 0px;");
      out.println("}");
      out.println(".break {");
      out.println("   page-break-after: always;");
      out.println("}");
      out.println(".structure {");
      out.println("   width: 100%;");
      out.println("   font-family: sans-serif;");
      out.println("   /* background-color: yellow; */");
      out.println("}");
      out.println(".structure td {");
      out.println("   border: 1px solid gray;");
      out.println("   padding-top: 2px;");
      out.println("}");
      out.println(".structure table td {");
      out.println("   border: none;");
      out.println("   padding: none;");
      out.println("}");
      out.println(".board {");
      out.println("   /* background-color: green; */");
      out.println("   display: block;");
      out.println("   padding: 0px;");
      out.println("   border-spacing: 0px;");
      out.println("   margin-bottom: -7em;");
      out.println("   position: relative;");
      out.println("   top: -5em;");
      out.println("}");
      out.println(".hand {");
      out.println("   list-style: none;");
      out.println("   /* background-color: red; */");
      out.println("   padding-left: 0px;");
      out.println("   font-size: 10px;");
      out.println("   width: 75px;");
      out.println("   margin: 0px;");
      out.println("}");
      out.println(".curtain {");
      out.println("   list-style: none;");
      out.println("   font-size: 12pt;");
      out.println("}");
      out.println(".direction {");
      out.println("   /* background-color: blue; */");
      out.println("}");
      out.println(".textcenter {");
      out.println("   text-align: center;");
      out.println("}");
      out.println(".center ul {");
      out.println("   margin-right: auto;");
      out.println("   margin-left: auto;");
      out.println("}");
      out.println(".textleft {");
      out.println("   text-align: left;");
      out.println("}");
      out.println(".left ul {");
      out.println("   margin-right: auto;");
      out.println("   margin-left: 0px;");
      out.println("}");
      out.println(".textright {");
      out.println("   text-align: right;");
      out.println("}");
      out.println(".right ul {");
      out.println("   margin-right: 0px;");
      out.println("   margin-left: auto;");
      out.println("}");
      out.println(".board tr {");
      out.println("   /* background-color: maroon; */");
      out.println("   width: 100%;");
      out.println("}");
      out.println(".board td {");
      out.println("   width: 1000px; ");
      out.println("}");
      out.println(".points {");
      out.println("   font-size: 9px; ");
      out.println("   border-spacing: 0px;");
      out.println("   position: relative;");
      out.println("   top: -10px;");
      out.println("   left: 10px;");
      out.println("   border: none;");
      out.println("   width: 4em;");
      out.println("   padding-right: 1px;");
      out.println("}");
      out.println(".tricks {");
      out.println("   font-size: 10px; ");
      out.println("   border-spacing: 0px;");
      out.println("   position: relative;");
      out.println("   top: 10px;");
      out.println("   left: 130px;");
      out.println("   border: 1px solid black;");
      out.println("   padding-right: 1px;");
      out.println("}");
      out.println(".tricks td {");
      out.println("   width: 1.2em; ");
      out.println("   text-align: right;");
      out.println("}");
      out.println("h1 { font-size: 12pt; margin: 5px;}");
      out.println(".permhead { font-size: 12pt; margin: 2px; }");
      out.println(".perm { font-size: 17pt; margin-top: 2px; }");
      out.println(".initperm { font-size: 12pt; margin: 2px; }");
      out.println(".number {");
      out.println("   position: relative;");
      out.println("   left: 0.5em;");
      out.println("   font-size: 16pt;");
      out.println("}");
      out.println(".vulnerability {");
      out.println("   position: relative;");
      out.println("   top: -5em;");
      out.println("   left: 14em;");
      out.println("   font-style: italic;");
      out.println("   font-size: 10px;");
      out.println("}");
      out.println(".stats {");
      out.println("   border-spacing: 20px;");
      out.println("}");
      out.println(".cell {");
      out.println("   height: 4cm;");
      out.println("}");
      out.println(".curtainback {");
      out.println("   margin-top: 2em;");
      out.println("   text-align: center;");
      out.println("   width: 100%;");
      out.println("   font-size: 14pt;");
      out.println("   font-weight: bold;");
      out.println("}");
      out.println(".break + tr { margin-top: 15px; }");
      out.println("-->");
      out.println("</style>");
      out.println("</head>");
      out.println("<body><h1>"+header+"</h1>");
   }
   private void startcell()
   {
      cellcount++;
      incell=true;
      out.println("<td class='cell'>");
   }
   private void startrow(int maxrows)
   {
      cellcount=0;
      inrow=true;
      rowcount++;
      if ( 0 == (rowcount % maxrows)) 
         out.println("<tr class='break'>");
      else
         out.println("<tr>");
   }
   private void startfulltable()
   {
      infulltable=true;
      out.println("<table class='structure'>");
   }
   private void stopcell()
   {
      out.println("</td>");
      incell=false;
   }
   private void stopfulltable()
   {
      infulltable=false;
      out.println("</table>");
   }
   private void stoprow()
   {
      inrow=false;
      out.println("</tr>");
   }
   public void printHand(int num, byte[][] hand)
   {
      if (!infulltable) startfulltable();
      if (!inrow) startrow(6);
      if (incell) stopcell();
      if (cellcount == MAXCELLS) { stoprow(); startrow(6); }
      startcell();
      String[] printablehand = getHandPrintables(hand);
      out.print("<h4 class='number'>");
      out.print(num);
      out.println("</h4>");
      out.print("<div class='vulnerability'>");
      out.print("Dlr: ");
      switch (num % 4) {
         case 1: out.print(PLAYER[NORTH]); break;
         case 2: out.print(PLAYER[EAST]); break;
         case 3: out.print(PLAYER[SOUTH]); break;
         case 0: out.print(PLAYER[WEST]); break;
      }
      out.println("<br/>");
      out.print("Vuln: ");
      switch (num % 16) {
            // ALL
            case 4:
            case 7:
            case 10:
            case 13:
               out.print("ALL");
               break;
            // N-S
            case 2:
            case 5:
            case 12:
            case 15:
               out.print("N-S");
               break;
            // E-W
            case 3:
            case 6:
            case 9:
            case 0:
               out.print("E-W");
               break;
            // NONE
            default:
               out.print("NONE");
      }
      out.print("</div>");
      //   0 
      // 3   1
      //   2
      out.println("<table class='board'>");

      // NORTH;
      out.println("<tr><td colspan='2' class='center'>");
      out.println("<ul class='hand'>");
      for (int i = 0; i < 4; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      out.println("</td></tr>");
      
      // WEST
      out.println("<tr><td class='left'>");
      out.println("<ul class='hand'>");
      for (int i = 4; i < 8; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      out.println("</td>");

      // EAST
      out.println("<td class='right'>");
      out.println("<ul class='hand'>");
      for (int i = 8; i < 12; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      out.println("</td></tr>");

      // SOUTH
      out.println("<tr><td colspan='2' class='center'>");
      out.println("<ul class='hand'>");
      for (int i = 12; i < 16; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      out.println("</td></tr>");
      out.println("</table>");
   }
   public void printCurtains(int num, byte[][] hand)
   {
      if (!infulltable) startfulltable();
      if (incell) stopcell();
      if (inrow) stoprow();
      inback=false;
      startrow(6);
      startcell();
      String[] printablehand = getHandPrintables(hand);
      out.println("<h4 class='curtainhead'>Board "+num+" "+PLAYER[NORTH]+"</h4>");
      out.println("<ul class='curtain'>");
      for (int i = 0; i < 4; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainhead'>Board "+num+" "+PLAYER[EAST]+"</h4>");
      out.println("<ul class='curtain'>");
      for (int i = 8; i < 12; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainhead'>Board "+num+" "+PLAYER[SOUTH]+"</h4>");
      out.println("<ul class='curtain'>");
      for (int i = 12; i < 16; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainhead'>Board "+num+" "+PLAYER[WEST]+"</h4>");
      out.println("<ul class='curtain'>");
      for (int i = 4; i < 8; i++) {
         out.print("<li>");
         out.print(printablehand[i]);
         out.println("</li>");
      }
      out.println("</ul>");
      stopcell();
   }
   public void printCurtainBack(int num)
   {
      if (!infulltable) startfulltable();
      if (incell) stopcell();
      if (inrow) stoprow();
      if (!inback) {
         out.println("<tr class='break'></tr>");
         rowcount=0;
      }
      inback=true;
      startrow(6);
      startcell();
      out.println("<h4 class='curtainback'>Board "+num+" "+PLAYER[WEST]+"</h4>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainback'>Board "+num+" "+PLAYER[SOUTH]+"</h4>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainback'>Board "+num+" "+PLAYER[EAST]+"</h4>");
      stopcell();
      startcell();
      out.println("<h4 class='curtainback'>Board "+num+" "+PLAYER[NORTH]+"</h4>");
      stopcell();
   }
   public void printPermutation1(int boardnum, byte[][] perm)
   {
      // TODO
   }
   public void printPermutation(int permnum, int boardnum, byte[] perm, byte[] initperm)
   {
      if (incell) stopcell();
      if (inrow) stoprow();
      if (infulltable) stopfulltable();
      out.println("<h4 class='permhead'>Board "+boardnum+" permutation "+permnum+"</h4>");
      
      if (null != initperm) {
         out.println("<p class='initperm'> Order the suits: ");
         for (int i = 0; i < 4; i++) {
            out.print("<b>");
            out.print(LONGSUIT[initperm[i] >> 4]);
            out.print("</b>");
            if (i < 3) out.print(", ");
         }
         out.println("</p>");
      }

      permcount++;
      
      if (0 == (permcount % 8))
         out.print("<p class='perm break'>");
      else
         out.print("<p class='perm'>");

      for (int k = 0; k < 52; k++) {
         out.print(perm[k]+1);
         if (3 == k % 4)
            out.print(" &nbsp; &nbsp; ");
         if (19 == k % 20) 
            out.println("<br/>");
      }
      out.println("</p>");
   }
   
   public void close()
   {
      if (incell) stopcell();
      if (inrow) stoprow();
      if (infulltable) stopfulltable();
      out.println("</body></html>");
      out.close();
   }

   public void printStats(double[] stats)
   {
      DecimalFormat df = new DecimalFormat("##.##");
      if (incell) stopcell();
      if (inrow) stoprow();
      if (infulltable) stopfulltable();
      out.print("<table>"); 

      out.print("<tr><td>North avg points: ");
      out.print(df.format(stats[STAT_NPOINTS]));
      out.println("</td>");
      out.print("<td>South avg points: ");
      out.print(df.format(stats[STAT_SPOINTS]));
      out.println("</td>");
      out.print("<td>East avg points: ");
      out.print(df.format(stats[STAT_EPOINTS]));
      out.println("</td>");
      out.print("<td>West avg points: ");
      out.print(df.format(stats[STAT_WPOINTS]));
      out.println("</td></tr>");
      
      out.print("<tr><td>North-South Games: ");
      out.print((int)stats[STAT_NSGAMES]);
      out.println("</td>");
      out.print("<td>East-West Games: ");
      out.print((int)stats[STAT_EWGAMES]);
      out.println("</td>");
      out.print("<td>North-South Slams: ");
      out.print((int)stats[STAT_NSSLAMS]);
      out.println("</td>");
      out.print("<td>East-West Slams: ");
      out.print((int)stats[STAT_EWSLAMS]);
      out.println("</td></tr>");
      
      out.print("<tr><td># 4333 Hands: ");
      out.print((int) stats[STAT_4333]);
      out.println("</td>");
      out.print("<td># Balanced Hands: ");
      out.print((int) stats[STAT_BAL]);
      out.println("</td>");
      out.print("<td># Semi-Balanced Hands: ");
      out.print((int) stats[STAT_SEMIBAL]);
      out.println("</td>");
      out.print("<td># 4441 Hands: ");
      out.print((int) stats[STAT_4441]);
      out.println("</td></tr>");
      
      out.print("<tr><td># 5-5 Hands: ");
      out.print((int) stats[STAT_55]);
      out.println("</td>");
      out.print("<td># 6+ Suits: ");
      out.print((int)stats[STAT_6PLUS]);
      out.println("</td>");
      out.print("<td># 7+ Suits: ");
      out.print((int)stats[STAT_7PLUS]);
      out.println("</td>");
      out.print("<td># 8+ Suits: ");
      out.print((int)stats[STAT_8PLUS]);
      out.println("</td></tr>");

      out.print("<tr><td># Voids: ");
      out.print((int)stats[STAT_VOID]);
      out.println("</td>");
      out.print("<td># Bacon Hands: ");
      out.print((int)stats[STAT_BACON]);
      out.println("</td></tr>");


      out.println("</table>");
   }

   public void printPoints(byte[] points)
	{
      if (!infulltable) startfulltable();
      if (!inrow) startrow(6);
      if (!incell) startcell();
      out.println("<table class='points'>");
      out.print("<tr>");
      out.print("<td colspan='2' class='textcenter'>");
		out.print(points[NORTH]);
      out.print("</td>");
      out.println("</tr>");
      out.print("<tr>");
      out.print("<td class='textleft'>");
		out.print(points[WEST]);
      out.print("</td>");
      out.print("<td class='textright'>");
		out.print(points[EAST]);
      out.print("</td>");
      out.println("</tr>");
      out.print("<tr>");
      out.print("<td colspan='2' class='textcenter'>");
		out.print(points[SOUTH]);
      out.print("</td>");
      out.println("</tr>");
      out.println("</table>");
	}
   public void printTricks(byte[] tricks)
   {
      if (!infulltable) startfulltable();
      if (!inrow) startrow(6);
      if (!incell) startcell();
      out.println("<table class='tricks'>");
      out.print("<tr>");
      out.print("<td></td>");
      out.print("<td>");
      out.print(SUIT[CLUBS>>4]);
      out.print("</td>");
      out.print("<td>");
      out.print(SUIT[DIAMONDS>>4]);
      out.print("</td>");
      out.print("<td>");
      out.print(SUIT[HEARTS>>4]);
      out.print("</td>");
      out.print("<td>");
      out.print(SUIT[SPADES>>4]);
      out.print("</td>");
      out.print("<td>");
      out.print(SUIT[NOTRUMPS>>4]);
      out.print("</td>");
      out.println("</tr>");
      out.print("<tr>");
      out.print("<td>N</td>");
      for (int i = 4; i >= 0; i--) {
         out.print("<td>");
         out.print(tricks[i]);
         out.print("</td>");
      }
      out.println("</tr><tr>");
      out.print("<td>S</td>");
      for (int i = 9; i >= 5; i--) {
         out.print("<td>");
         out.print(tricks[i]);
         out.print("</td>");
      }
      out.println("</tr><tr>");
      out.print("<td>E</td>");
      for (int i = 14; i >= 10; i--) {
         out.print("<td>");
         out.print(tricks[i]);
         out.print("</td>");
      }
      out.println("</tr><tr>");
      out.print("<td>W</td>");
      for (int i = 19; i >= 15; i--) {
         out.print("<td>");
         out.print(tricks[i]);
         out.print("</td>");
      }
      out.println("</tr>");
      out.println("</table>");
   }
   public void println(String s)
   {
      out.print(s);
      out.println("<br/>");
   }
   public void print(String s)
   {
      out.print(s);
   }
}

