maxWords = 30;
maxWidth = 15;
maxHeight = 20;
wdcnt = 0;
grid = new Array(maxWidth);
wordStart = new Array(maxWidth);
wd = new Array(maxWords);
cl = new Array(maxWords);
wdused = new Array(maxWords);
wordX = new Array(maxWords);
wordY = new Array(maxWords);
wddir = new Array(maxWords);
letterList = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
line = "hr";
tgraph = "";
pgraph = "";
pid = "";
puzzMade = false;
useX = maxWidth;
useY = maxHeight;
wide = 0;
high = 0;
useCount = 0;


function ScoreWord(word, wx, wy, d) {
    var mt = 1;
    var s = 0;
    
    if (d) {
        var dx = 1;
        var dy = 0;
    }
    if (! d) {
        var dx = 0;
        var dy = 1;
    }
   
    for (var x=0;x<(word.length);x++) {
        var ch = word.substring(x,x+1);
        if ((ch == "B") || (ch == "E") || (ch == "T") || (ch == "W"))
            s = s + 1;
        if ((ch == "I") || (ch == "S") || (ch == "O"))
            s = s + 1;
        if ((ch == "A") || (ch == "R") || (ch == "N"))
            s = s + 2;
        if ((ch == "C") || (ch == "L"))
            s = s + 2;
        if ((ch == "H") || (ch == "D") || (ch == "P"))
            s = s + 3;
        if ((ch == "F") || (ch == "M") || (ch == "U"))
            s = s + 3;
        if ((ch == "G") || (ch == "V") || (ch == "Y") || (ch == "W"))
            s = s + 4;
        if ((ch == "X") || (ch == "K") || (ch == "B"))
            s = s + 4;
        if (ch == "Q")
            s = s + 5;
        if ((ch == "J") || (ch == "Z"))
            s = s + 5;

        if ((wx + (x * dx) >= 0) && (wx + (x * dx) < useX) && (wy + (x * dy) >= 0) && (wy + (x * dy) < useY)) {
            if (word.substring(x,x+1) == grid[wx + (x * dx)][wy + (x * dy)]) 
                if (mt > 0)
                    mt = mt + 1;
            if (word.substring(x,x+1) != grid[wx + (x * dx)][wy + (x * dy)]) {
                if (grid[wx + (x * dx)][wy + (x * dy)] != "")
                    mt = 0;
                if (grid[wx + (x * dx) + dy][wy + (x * dy) + dx] != "")
                    mt = 0;
                if (grid[wx + (x * dx) - dy][wy + (x * dy) - dx] != "")
                    mt = 0;
            }
        }

        if ((wx + (x * dx) < 0) || (wx + (x * dx) >= useX) || (wy + (x * dy) < 0) || (wy + (x * dy) >= useY))
            mt = 0;
        if (mt == 0) 
            x = word.length;
    }

    if (((wx - dx) >= 0) && ((wx - dx) <= useX) && ((wy - dy) >= 0) && ((wy - dy) <= useY))
        if (grid[wx - dx][wy - dy] != "")
            mt = 0;
    if (((wx + (dx * word.length)) >= 0) && ((wx + (dx * word.length)) <= useX) && ((wy + (dy * word.length)) >= 0) && ((wy + (dy * word.length)) <= useY))
        if (grid[wx + (dx * word.length)][wy + (dy * word.length)] != "")
            mt = 0;
    return (s * mt);
}

function PlaceWord(fx, fy, f, d, w) {
    var ok = true;

    if (d) {
        var dx = 1;
        var dy = 0;
    }
    if (! d) {
        var dx = 0;
        var dy = 1;
    }
    
    var x = (fx - ((f - 1) * dx));
    var y = (fy - ((f - 1) * dy));
    for (var i=0;i<w.length;i++) {
        if ((x + (i * dx) >= 0) && (x + (i * dx) < useX) && (y + (i * dy) >= 0) && (y + (i * dy) <= useY))
            if (grid[x + (i * dx)][y + (i * dy)] != "") 
                if (grid[x + (i * dx)][y + (i * dy)] != w.substring(i,i+1))
                    ok = false;
        if ((x + (i * dx) < 0) || (x + (i * dx) >= useX) || (y + (i * dy) < 0) || (y + (i * dy) >= useY))
            ok = False;
    }
    
    if (ok)
        for (var i=0;i<w.length;i++) 
            grid[x + (i * dx)][y + (i * dy)] = w.substring(i,i+1);
    
    return (ok);
}

function LetterCount(w, l) {
    var ct = 0;
    var tw = w.toUpperCase(w);
    l = l.toUpperCase(l);
    
    while (tw.indexOf(l) >= 0) {
        ct = ct + 1;
        tw = tw.substring(tw.indexOf(l)+1,tw.length);
    }
    return (ct);
}

function LetterPos(w, l, c) {
    var ps = 0;
    var tc = c;
    var tw = w.toUpperCase(w);
    l = l.toUpperCase(l);
    
    while (tc > 0) {
        ps = ps + tw.indexOf(l);
        tw = tw.substring(tw.indexOf(l)+1,tw.length);
        tc = tc - 1;
        if (tw.indexOf(l) < 0) 
            tc = 0;
    }
    return (ps);
}

function makePuzzle() {
    puzzMade = false;

    wdcnt = 0;

window.status = "Loading word list...";
    for (var i=0; i<maxWords; i++) {
        var word = eval("document.getWords.word" + i + ".value");
        if (word.length>0) {
            wd[wdcnt] = word.toUpperCase(word);
            word = eval("document.getWords.clue" + i + ".value");
            if (word.length>0)
                cl[wdcnt] = word.toUpperCase(word);
            wdcnt = wdcnt+1;
        }
        wdused[i] = false;
        wordX[i] = 0;
        wordY[i] = 0;
        wddir[i] = false;
    }
    wdcnt = wdcnt - 1;

window.status = "Setting up grid system...";
    wide = maxHeight;
    high = maxWidth;

    useX = wide;
    useY = high;
    for (var x=0;x<wide;x++) {
        grid[x] = new Array(high);
        wordStart[x] = new Array(high);
        for (var y=0;y<high;y++) {
            grid[x][y] = "";
            wordStart[x][y] = false;
        }
    }
                
    window.status = "Generating puzzle...";
    GeneratePuzzle();
}


function makePuzzPage(solve) {
    for (var c=0;c<document.getOpts.elements.length;c++)
        if (document.getOpts.elements[c].checked)
        {
            if (document.getOpts.elements[c].name == "line")
            {
                if (document.getOpts.elements[c].value == 0)
                    line = "";
                if (document.getOpts.elements[c].value == "hr")
                    line = "hr";
                if ((document.getOpts.elements[c].value != 0) && (document.getOpts.elements[c].value != "hr"))
                    line = eval("document." + document.getOpts.elements[c].value + ".src");
            }
            if (document.getOpts.elements[c].name == "title")
            {
                if (document.getOpts.elements[c].value == 0)
                    tgraph = "";
                if (document.getOpts.elements[c].value != 0)
                    tgraph = eval("document." + document.getOpts.elements[c].value + ".src");
            }
            if (document.getOpts.elements[c].name == "puzzgraph")
            {
                if (document.getOpts.elements[c].value == 0)
                    pgraph = "";
                if (document.getOpts.elements[c].value != 0)
                    pgraph = eval("document." + document.getOpts.elements[c].value + ".src");
            }
        }


window.status = "Generating page...";
        if (puzzMade)
        {
            puzzWin = window.open("", "wordsearch",'toolbar=yes,location=yes,directories=no,status=yes,scrollbars=yes,menubar=yes,resizable=yes,width=600,height=440');
            puzzWin.document.writeln("<head><title>" + document.getWords.title.value + "</title></head>");
            puzzWin.document.write("<body");
            puzzWin.document.writeln(">");

            puzzWin.document.writeln("<font face=\"Arial\"><center><table cellspacing=0 cellpadding=3><tr bgcolor=\"#FFFFFF\"><td>");
            if (tgraph != "")
                puzzWin.document.write("<td><img align=\"middle\" src=\"" + tgraph + "\"></td><td>");
            puzzWin.document.write("<font size=\"+2\"><b>" + document.getWords.title.value + "</b></font>");
            if (tgraph != "")
                puzzWin.document.write("</td><td><img align=\"middle\" src=\"" + tgraph + "\">");
            puzzWin.document.writeln("</td></tr></table></center>");
            if (line == "hr")
                puzzWin.document.writeln("<hr>");
            if (line != "hr")
            {
                if (line != "")
                    puzzWin.document.writeln("<p><center><img src=\"" + line + "\"></center><p>");
                if (line == "")
                    puzzWin.document.writeln("<br><p>");
            }

window.status = "Adding instructions...";

window.status = "Adding puzzle...";
            var cluecount = 0;

            puzzWin.document.writeln("<p><table border=0 align=\"center\" cellpadding=0 cellspacing=0>");
            for (var y=0;y<useY;y++) {
                puzzWin.document.write("<tr>");
                for (var x=0;x<useX;x++) {
                    puzzWin.document.write("<td>");
                    var showit = false;
                    if (grid[x][y] != "")
                        showit = true;
                    if (x > 0)
                        if (grid[x-1][y] != "")
                            showit = true;
                    if (y > 0)
                        if (grid[x][y-1] != "")
                            showit = true;
                    if ((x > 0) && (y > 0))
                        if (grid[x-1][y-1] != "")
                            showit = true;
                    if (showit)
                        puzzWin.document.write("<img src=\"corner.gif\">");
                    if (! showit)
                        puzzWin.document.write("<img src=\"bcorner.gif\">");
                    puzzWin.document.write("</td>");
                    puzzWin.document.write("<td><img src=\"");
                    showit = false;
                    if (grid[x][y] != "")
                        showit = true;
                    if (y > 0)
                        if (grid[x][y-1] != "")
                            showit = true;
                    if (showit)
                        puzzWin.document.write("hline.gif");
                    if (! showit)
                        puzzWin.document.write("bhline.gif");
                    puzzWin.document.write("\"></td>");
                    if (x == (useX - 1)) {
                        puzzWin.document.write("<td>");
                        showit = false;
                        if (grid[x][y] != "")
                            showit = true;
                        if (y > 0)
                            if (grid[x][y-1] != "")
                                showit = true;
                        if (showit)
                            puzzWin.document.write("<img src=\"corner.gif\">");
                        if (! showit)
                            puzzWin.document.write("<img src=\"bcorner.gif\">");
                        puzzWin.document.write("</td>");
                    }
                }

                puzzWin.document.write("</tr><tr>");
                for (var x=0;x<useX;x++) {
                    puzzWin.document.write("<td><img src=\"");
                    showit = false;
                    if (grid[x][y] != "")
                        showit = true;
                    if (grid[x][y] == "")
                        if (x > 0)
                            if (grid[x-1][y] != "")
                                showit = true;
                    if (showit)
                        puzzWin.document.write("vline.gif");
                    if (! showit)
                        puzzWin.document.write("bvline.gif");
                    puzzWin.document.write("\"></td>");
                    puzzWin.document.write("<td");
                    if (grid[x][y] != "") {
                        puzzWin.document.write(" bgcolor=\"#FFFFFF\"");
                        if (wordStart[x][y]) {
                            cluecount = cluecount + 1
                            puzzWin.document.write("valign=\"top\"><font size=\"-2\"><super>" + cluecount + "</super></font><br");
                        }
                        if (solve)
                            puzzWin.document.write("><center>" + grid[x][y] + "</center>");
                    }
                    if (grid[x][y] == "")
                         puzzWin.document.write("><center><img src=\"back.gif\"></center>");
                    puzzWin.document.write("</td>");
                    if (x == (useX - 1)) {
                        puzzWin.document.write("<td>");
                        if (grid[x][y] != "")
                            puzzWin.document.write("<img src=\"vline.gif\">");
                        if (grid[x][y] == "")
                            puzzWin.document.write("<img src=\"bvline.gif\">");
                        puzzWin.document.write("</td>");
                    }
                }
                puzzWin.document.writeln("</tr>");
            }

            puzzWin.document.write("<tr>");
            for (var x=0;x<useX;x++) {
                puzzWin.document.write("<td>");
                var showit = false;
                if (grid[x][useY-1] != "")
                    showit = true;
                if (x > 0)
                    if (grid[x-1][useY-1] != "")
                        showit = true;
                if (showit)
                    puzzWin.document.write("<img src=\"corner.gif\">");
                if (! showit)
                    puzzWin.document.write("<img src=\"bcorner.gif\">");
                puzzWin.document.write("</td>");
                puzzWin.document.write("<td>");
                if (grid[x][useY-1] != "")
                    puzzWin.document.write("<img src=\"hline.gif\">");
                if (grid[x][useY-1] == "")
                    puzzWin.document.write("<img src=\"bhline.gif\">");
                puzzWin.document.write("</td>");
                if (x == (useX - 1)) {
                    puzzWin.document.write("<td>");
                    if (grid[x][useY-1] != "")
                        puzzWin.document.write("<img src=\"corner.gif\">");
                    if (grid[x][useY-1] == "")
                        puzzWin.document.write("<img src=\"bcorner.gif\">");
                    puzzWin.document.write("</td>");
                }


            }
            puzzWin.document.writeln("</table><p>");

            puzzWin.document.writeln("<table align=\"center\"><tr><td colspan=3 bgcolor=\"#D0D0D0\"><center><b><font size=\"+1\">Clues:</font></b></center></td></tr>");
            puzzWin.document.writeln("<tr><td width=250 valign=\"top\"><b>Across:</b><hr>");
            cluecount = 0;
            for (var y=0;y<useY;y++)
                for (var x=0;x<useX;x++)
                    if (wordStart[x][y]) {
                        cluecount = cluecount + 1;
                        for (var wi=0;wi<wdcnt;wi++)
                            if ((wordX[wi] == x) && (wordY[wi] == y) && wddir[wi]) {
                                puzzWin.document.writeln("<b>" + cluecount + ".</b> " + cl[wi] + "<br>");
                                wi = wdcnt;
                            }
                    }
            puzzWin.document.writeln("</td><td width=10></td><td valign=\"top\" width=250>");
            puzzWin.document.writeln("<b>Down:</b><hr>");
            cluecount = 0;
            for (var y=0;y<useY;y++)
                for (var x=0;x<useX;x++)
                    if (wordStart[x][y]) {
                        cluecount = cluecount + 1;
                        for (var wi=0;wi<wdcnt;wi++)
                            if ((wordX[wi] == x) && (wordY[wi] == y) && (! wddir[wi])) {
                                puzzWin.document.writeln("<b>" + cluecount + ".</b> " + cl[wi] + "<br>");
                                wi = wdcnt;
                            }
                    }
            puzzWin.document.writeln("</td></tr></table><p>");


window.status = "Adding footer...";
            if (line == "hr")
                puzzWin.document.writeln("<hr>");
            if (line != "hr")
            {
                if (line != "")
                    puzzWin.document.writeln("<p><center><img src=\"" + line + "\"></center><p>");
                if (line == "")
                    puzzWin.document.writeln("<br><p>");
            }

            AddFooter();

            puzzWin.document.close();
            puzzWin.focus();
        }
        if (! puzzMade)
            alert("You must click on the 'Make Puzzle' button first.");
window.status="";
}

function GeneratePuzzle() {
    var s = 0;
    var wx = 0;
    var wy = 0; 
    var wdelta = false;
    var hs = 0;
    var hx = 0;
    var hy = 0;
    var hwd = false;
    var hi = 0;
    var hwrd = 0;
    var hpc = 0;
    var i = 0;
    var inWord = 0;
    var z = 0;
    var lPlace = 0;
    useCount = 0;
    var changeMade = true;

    for (var x=0;x<wdcnt;x++) {
        var y = ScoreWord(wd[x], 1, 1, true);
        if (y > s) {
            s = y;
            i = x;
        }
    }

    wddir[i] = (Math.random() < 0.5);
    if (wddir[i]) {
        wx = Math.round(useX / 2) - Math.round(wd[i].length / 2) + 1;
        wy = Math.round(useY / 2);
    }
    if (! wddir[i]) {
        wx = Math.round(useX / 2);
        wy = Math.round(useY / 2) - Math.round(wd[i].length / 2) + 1;
    }
    wordX[i] = wx;
    wordY[i] = wy;
    wordStart[wx][wy] = true;
    
    if (PlaceWord(wx, wy, 1, wddir[i], wd[i])) {
        wdused[i] = true;
        while ((useCount < wdcnt) && (changeMade)) {
            changeMade = false;
            for (var y=0;y<useY;y++)
                for (var x=0;x<useX;x++)
                    if (grid[x][y] != "") {
                        hs = 0;
                        for (var wi=0;wi<wdcnt;wi++)
                            if (! wdused[wi])
                                if (wd[wi].indexOf(grid[x][y]) >= 0) {
                                    var inWord = LetterCount(wd[wi], grid[x][y]);
                                    for (var z=1;z<=inWord;z++) {
                                        lPlace = LetterPos(wd[wi], grid[x][y], z);
                                        wdelta = (Math.random() < 0.5);
                                        if (wdelta) {
                                            wx = x - (lPlace);
                                            wy = y;
                                        }
                                        if (! wdelta) {
                                            wx = x;
                                            wy = y - (lPlace);
                                        }
                                        if ((wx >= 0) && (wx <= useX) && (wy >= 0) && (wy <= useY)) {
                                            s = ScoreWord(wd[wi], wx, wy, wdelta);
                                            if (s > hs) {
                                                hx = wx;
                                                hy = wy;
                                                hwd = wdelta;
                                                hwrd = wi;
                                                hi = z;
                                                hpc = lPlace;
                                                hs = s;
                                            }
                                        }
                                    }
                                }
                        if (hs > 0)
                            if (PlaceWord(hx, hy, 1, hwd, wd[hwrd])) {
                                hs = 0;
                                wdused[hwrd] = true;
                                wordX[hwrd] = hx;
                                wordY[hwrd] = hy;
                                wordStart[hx][hy] = true;
                                wddir[hwrd] = hwd;
                                changeMade = true;
                            }
                    }
        }

        while (MoveUp()) {
        }
        while (MoveLeft()) {
        }
        
        var ok = true;
        while (ok) {
            for (var x=0;x<useX;x++)
                if (grid[x][useY-1] != "")
                    ok = false;
            if (ok)
                useY = useY - 1;
        }
        ok = true;
        while (ok) {
            for (var y=0;y<useY;y++)
                if (grid[useX-1][y] != "")
                    ok = false;
            if (ok)
                useX = useX - 1;
        }
        puzzMade = true;

        getWorksheetID();
        window.status = "Puzzle completed, click on 'Show Worksheet' or 'Show Answer Key'.";
    }
}

function MoveUp() {
    var ok = true;
    for (var x=0;x<useX;x++)
        if (grid[x][0] != "")
            ok = false;
    if (ok)  {
        for (var y=0;y<(useY-1);y++)
            for (var x=0;x<useX;x++) {
                grid[x][y] = grid[x][y + 1];
                wordStart[x][y] = wordStart[x][y + 1];
            }
        for (var x=0;x<useX;x++) {
            grid[x][useY-1] = "";
            wordStart[x][useY-1] = false;
        }
        for (var x=0;x<wdcnt;x++)
            if (wordY[x] > 0)
                wordY[x] = wordY[x] - 1;
    }
    return (ok);
}

function MoveLeft() {
    var ok = true;
    for (var y=0;y<useY;y++)
        if (grid[0][y] != "")
            ok = false;
    if (ok) {
        for (var x=0;x<(useX-1);x++)
            for (var y=0;y<useY;y++) {
                grid[x][y] = grid[x + 1][y];
                wordStart[x][y] = wordStart[x + 1][y];
            }
        for (var y=0;y<useY;y++) {
            grid[useX-1][y] = "";
            wordStart[useX-1][y] = false;
        }
        for (var y=0;y<wdcnt;y++)
            if (wordX[y] > 0)
                wordX[y] = wordX[y] - 1;
    }
    return (ok);
}

