/*
 * Cruciverb v1.0 - Crossword App
 *
 * Copyright (c) 2008 Jim Krehl (http://jimmyk.org)
 * Licensed under the GPL (http://www.gnu.org/licenses/gpl.txt)
 *
 * Date: Wed Oct  8 16:22:44 EDT 2008
 */
function Puzzle (data)
{
	if (data != null) {
		this.data = data;

		this.cursor = 0x2C;

		this.width = this.height = this.data.charCodeAt (this.cursor);
		this.cells = [];

		this.cursor = 0x34;
		label       = 0;

		across_label = 0;
		down_labels  = [];

		for (j = 0; j < this.height; ++j) {
			this.cells [j] = [];

			for (i = 0; i < this.width; ++i) {
				c = this.data.charAt (this.cursor ++);

				if (c == '.')
					this.cells [j] [i] = new Cell (i, j, Puzzle.BLANK_CELL, -1, -1);
				else if (
					(i == 0 || this.cells [j] [i - 1].label == Puzzle.BLANK_CELL) ||
					(j == 0 || this.cells [j - 1] [i].label == Puzzle.BLANK_CELL)
				) {
					++ label;

					if (i == 0 || this.cells [j] [i - 1].label == Puzzle.BLANK_CELL)
						across_label = label;

					if (j == 0 || this.cells [j - 1] [i].label == Puzzle.BLANK_CELL)
						down_labels [i] = label;

					this.cells [j] [i] = new Cell (i, j, label, across_label, down_labels [i]);
				}
				else
					this.cells [j] [i] = new Cell (i, j, Puzzle.UNLABELED_CELL, across_label, down_labels [i]);
			}
		}

		this.cursor += this.width * this.height;

		this.title     = this.popString ();
		this.author    = this.popString ();
		this.copyright = this.popString ();  // FIXME: charset not recognize &copy;

		this.acrossClues = [];
		this.downClues   = [];

		for (j = 0; j < this.height; ++j) {
			for (i = 0; i < this.width; ++i) {
				if (this.cells [j] [i].label > 0) {
					if (i == 0 || this.cells [j] [i - 1].label == Puzzle.BLANK_CELL) {
						coords = [];
						coords [0] = i;
						coords [1] = j;

						this.acrossClues [this.cells [j] [i].label] = new Clue (
							true, this.cells [j] [i].label,
							this.popString (), coords);
					}

					if (j == 0 || this.cells [j - 1] [i].label == Puzzle.BLANK_CELL) {
						coords = [];
						coords [0] = i;
						coords [1] = j;

						this.downClues [this.cells [j] [i].label] = new Clue (
							false, this.cells [j] [i].label,
							this.popString (), coords);
					}
				}
			}
		}
	}

	else {
		this.title     = "Cruciverb 1.0";
		this.author    = "Jim Krehl";
		this.copyright = "&copy; 2008";

		this.width = this.height = 15;

		this.cells = [];
	
		for (j = 0; j < 15; ++j) {
			this.cells [j] = [];

			for (i = 0; i < 15; ++i)
				this.cells [j] [i] = new Cell (i, j, Puzzle.UNLABELED_CELL, -1, -1);
		}
	}
}

Puzzle.prototype.popString = function ()
{
	while (this.cursor < this.data.length && this.data.charCodeAt (this.cursor) <= 0)
		++ this.cursor;

	s_0 = this.cursor;

	while (this.cursor < this.data.length && this.data.charCodeAt (this.cursor) > 0)
		++ this.cursor;

	return $.trim (this.data.substring (s_0, this.cursor));
}

Puzzle.BLANK_CELL     = -1;
Puzzle.UNLABELED_CELL =  0;

Puzzle.prototype.isBlankCell = function (coords)
{
	return this.cells [coords [1]] [coords [0]].label == Puzzle.BLANK_CELL;
}

function Cell (x, y, l, ac, dc) {
	this.x          = x;
	this.y          = y;

	this.label      = l;

	this.acrossClue = ac;
	this.downClue   = dc;
}

function Clue (across, label, text, start)
{
	this.across = across;
	this.label  = label;
	this.text   = text;
	this.start  = start;
}
