var errorspot = "dynamic";
var navstate = {current:'', data:[]};
var mobile = 0;
var c4new, c4invis;

function navstate2display() {
    var sb = [];
    var rowtemplate = '<tr id="steprow_xcount"xpicked><td class="cClick c1"><img src="/static/steparrow.gif" alt="&gt;" class="steparrow"/></td><td class="cClick c2 u">xlabel</td><td class="cClick c3">xdeletecell</td>xc4</tr>';
    var deletecell = '<img src="/static/deletebutton.gif" alt="X" title="Delete" />';
    var numcounts = $.grep(navstate.data, function(x){ return x['name'].match(/^Count/);  }).length;
    if (! mobile) {
        c4new = '<td class="cNew c4" id="addcount"><img src="/static/addbutton.gif" alt="+" class="padleft" />&nbsp;<span class="u">Add count ' + (numcounts + 1) + '</span></td>';
        c4invis = '<td class="c4 invisible"><img src="/static/addbutton.gif" alt="+" class="padleft invisible" />&nbsp;<span class="u invisible">Add count X</span></td>';
    }
    $.each(navstate.data, function(i,x){ 
        var xcount = i + "";
        var xlabel = x.name;
        var xdelete = (numcounts > 1 && xlabel.match(/^Count \d+: \d/  ) ? deletecell : "&nbsp;");
        var xc4 = (xlabel.match(RegExp("^Count " + numcounts))  && (!  xlabel.match(/(new)/) ) ? c4new : c4invis);
        var xpicked = (x.value == navstate.current ? ' class="picked"' : "");
        sb.push(rowtemplate.replace(/xcount/g, xcount).replace(/xlabel/g, xlabel).replace(/xdeletecell/, xdelete).replace(/xc4/, xc4).replace(/xpicked/, xpicked));
    });
    $("#stepstb").html( sb.join("\n") );
    setEventListeners();
}

function sendAnswer(el) {
    var d = {};
    $("*",$(el).parents("form:first")).filter("*[name]").each(function(){ 
        var thisJ = $(this);
        var nm = thisJ.attr("name");
        if (thisJ.attr("type") == "checkbox") {
            d[nm] = this.checked ? "on" : "F";
        } else {
            d[nm] = thisJ.val();
        }
    });
    $.post("/dynamic/", d, addblock);
    if ("question" in d)
        errorspot = "q" + d['question'] + "form";
}

function userClick(e) {
    sendAnswer(this);
    if ($(this).attr('type') == "submit") {
        if (e.stopPropagation) { e.stopPropagation(); }
        if (e.preventDefault) { e.preventDefault(); }
    }
}

var textMemory = {};
function textblur() {
    var thisJ = $(this);
    var id = thisJ.attr("id");
    var content = thisJ.val();
    if ( !(id in textMemory)) textMemory[id] = "";
    if ( textMemory[id] != content ) {
        textMemory[id] = content;
        sendAnswer(this);
    }
}

function codePick(e) {
    var el = e.target ? e.target : e.srcElement;
    var spl = $(el).val().split("_");
    if (spl.length < 2) return;
    var selectid = $(el).attr("id");
    $("#" + selectid.replace("codepick","title")).val(spl[0]);
    $("#" + selectid.replace("codepick","section")).val(spl[1]);
}


function displayCorrectQuestions() {
    var correctClass = "context" + navstate.current;
    $("form.question,h3.message")      // All questions and messages
        .filter("*:not([class*="+correctClass+"])")    // That are not of the current context
            .hide()     // Are hidden
        .end()
        .filter("*[class*="+correctClass+"]")  // All questions that are of the current context
            .filter("*:not([class*=hiding])")  // And do not have the "hiding" class
                .show();        // Are shown
}

function groupingChange(element) {
    var e = element.target ? element.target : element.srcElement; //check
    var re = $(e).val().match(/m(....)g(\d+)/);
    if (!re || re.length < 3)
        return;
    var moveId = re[1];
    var toGroup = re[2];
    var groupingForm = $(e).parents("form");
    var hiddenField = $("input:hidden",groupingForm);
    var bluePrintString = hiddenField.val();
    var bluePrint = eval( '(' + bluePrintString.replace(/-/g,"'") + ')');
    for (var i = 0; i < bluePrint.length; i++)
        bluePrint[i] = $.grep(bluePrint[i], function(a){return a != moveId;});
    if (! bluePrint[toGroup])
        bluePrint[toGroup] = [];
    bluePrint[toGroup].push(moveId);
    var idToNum = {}
    $.each(navstate.data, function(i,x){ 
        var c = (x.name).match(/Count (\d+)/);
        if (c && c.length > 1)
            idToNum[ x.value ] = parseInt(c[1]);
    });
    bluePrint[toGroup].sort(function(a,b){ return idToNum[a] - idToNum[b]; });
    bluePrint = $.grep(bluePrint, function(a){return a && a.length > 0});
    function idToString(x) { return "-" + x + "-"; }
    function sublist(x) { return "[" + $.map(x, idToString).join(", ") + "]"; }
    var newBPS = "[" + $.map(bluePrint, sublist).join(", ") + "]";
    hiddenField.val(newBPS);

    var formId = $(groupingForm).attr("id");
    var questionId = formId.match(/^q(.*?)form$/)[1];
    $.post("/dynamic/", { question : questionId, answer : newBPS }, addblock );
    errorspot = formId;
    $(groupingForm).each(buildGroupQuestionForm); 
}

function buildGroupQuestionForm() {
    var thisId = $(this).attr("id");
    var bluePrintStr = $("input:hidden",this).val().replace(/-/g, "'");
    var bluePrint = eval("(" + bluePrintStr +")");
    var idToName = {};
    var numGroups = bluePrint.length;

    var countsArray = $.grep(navstate.data, function(x) { return x.name.match(/^Count \d+: \d/); });
    var numCounts = countsArray.length;
    $.each(countsArray, function(i,x){ idToName[ x.value ] = x.name; });
    
    var iH = '<input type="hidden" value="' + bluePrintStr.replace(/'/g,"-") + '" />'
        +'<div class="groupQuestionLabel">' + $("div.groupQuestionLabel", this).html() + "</div>"
        + $.map(bluePrint, function(countList, groupNum){ 
            var fs = [ '<fieldset id="groupGN1" class="group"><legend>Group GN1</legend><ul>'.replace(/GN1/g, groupNum + 1) ];
            $.merge(fs, $.map(countList, function(countId) {
                var li = ['<li>NAME&nbsp;<select id="sIDcidCOUNTID"><option value="none">Move&hellip;</option>'
                            .replace(/NAME/, idToName[countId])
                            .replace(/ID/, thisId)];
                for (var i = 0; i < numGroups; i++) {
                    if (i != groupNum)
                        li.push('<option value="mCOUNTIDg' + i + '">Group ' + (i+1) + '</option>');
                }
                if (numGroups < numCounts)
                    li.push('<option value="mCOUNTIDg' + (numGroups+1) + '">New group</option>');
                li.push('</select></li>');
                return li.join("").replace(/COUNTID/g, countId);
            }));
            fs.push('</ul></fieldset>');
            return fs.join("");
        }).join("");
    $(this).html(iH);
    $('select', this).change(groupingChange);
}

function stopEnter(e) {
    var charcode = e.which ? e.which : e.keyCode;
    if (charcode == 13) {
        $(this).blur();
        return false;
    }
    return true; 
}

var seen = {};

function addblock(json) {
    if ("report" in json) {
        $("#reportspot").html(json["report"]);
    }
    var mustBuildGroups = false;
    var mustDrawSteps = false;
    var mustDisplayCorrectQuestions = false;
    var i, ordinal, goesafter, questionMessageChronology, qid, qmc, qmcid;
    var qDict = {};
    var mDict = {};
    if ("questions" in json) 
        $.each(json["questions"], function(i, question) { qid = /q(.+)form/.exec(question.id)[1]; qDict[qid] = question; });
    if ("messages" in json)
        $.each(json["messages"], function(i, message) {mDict[message.id] = message; });
    if ("questions" in json || "messages" in json) {
        mustDisplayCorrectQuestions = true;
        for (ordinal = 0, qmc = json["questionMessageChronology"]; ordinal < qmc.length; ordinal++) {
            qmcid = qmc[ordinal];
            if (qmcid in seen) continue;
            seen[qmcid] = (qmcid in qDict ? 1 : 2);
            goesafter = ( ordinal == 0 ? "dynamic" : qmc[ordinal - 1] );
            if (seen[goesafter] == 1) goesafter = "q" + goesafter + "form";
            if (qmcid in qDict) {
                question = qDict[qmcid];
                $("*",$(question['html']).insertAfter("#" + goesafter))
                    .filter('input[type="checkbox"],input[type="submit"]').click(userClick).end()
                    .filter('input:text:not([class*=noblur])').blur(textblur).end()
                    .filter('input:text').keypress(stopEnter).end()
                    .filter('select:not([class*=codepick])').change(userClick).end()
                    .filter('select:[class*=codepick]').change(codePick).end()
                    .filter('label,input').add('body')
                        .ajaxStart( function(){$(this).css({cursor:"wait"});} ) 
                        .ajaxStop( function(){$(this).css({cursor:"auto"});} );
                mustBuildGroups = mustBuildGroups || (question["html"].indexOf("groupquestion") > -1);
            } else {
                message = mDict[qmcid];
                $("*",$(message['html']).insertAfter("#" + goesafter));
            }
        }
    }

    if ('contextJSON' in json) {
        navstate.data = json['contextJSON'];
        mustBuildGroups = true;
        mustDrawSteps = true;
        mustDisplayCorrectQuestions = true;
    }

    if ("selectContext" in json) {
        navstate.current = json['selectContext'];
        mustDisplayCorrectQuestions = true;
        mustDrawSteps = true;
    }
    if ("questionsOnPage" in json) {
        var keepOnPage = {};
        $.each(json["questionsOnPage"], function(i, x) { 
            keepOnPage["q" + x + "form"] = 1;
            keepOnPage[x] = 1;
        });
        $("form.question,h3.message").each( function() {
            var thisJ = $(this);
            if ( thisJ.attr('id') in keepOnPage  ) {
                thisJ.removeClass("hiding");
            } else {
                thisJ.addClass('hiding').hide();
            }
        });
        mustDisplayCorrectQuestions = true;
    }
    if ("error" in json) {
        $("#" + errorspot).append(json["error"]);
    } else $("#" + errorspot).hide();
    if (mustBuildGroups)
        $("form.groupquestion").each(buildGroupQuestionForm);
    if (navstate.current == '' && navstate.data.length > 0)
        navstate.current = navstate.data[0].value
    if (mustDrawSteps)
        navstate2display();
    if (mustDisplayCorrectQuestions)
        displayCorrectQuestions();
}

function getRowNumber(e) {
    var tr = $(e).parents("tr[id]").get(0);
    var trid = $(tr).attr("id");
    var tridre = trid.match(/steprow_(\d+)/);
    if (tridre && tridre.length > 0) {
       return parseInt(tridre[1]);
    }
    return null;
}

function rowClicked() { 
    var row = getRowNumber(this);
    if (row == null) return;
    $("#stepstb tr").removeClass("picked");
    $("#steprow_" + row).addClass("picked");
    navstate.current = navstate.data[row].value;
    displayCorrectQuestions();
}

function setEventListeners() {
    $(".cClick, .cNew").hover(function(){ 
      $(this).css({cursor:'pointer'}); 
     },function(){ 
        $(this).css({cursor:'auto'}); 
     });
    $(".cClick").click(rowClicked);
    $(".cNew").click(function(e){ $.post("/dynamic/", {"addCount":"1"}, addblock ); });

    $(".c3 img").click(function(e){ 
        var row = getRowNumber(this);
        if (confirm("Really delete "+ navstate.data[row].name.replace("&nbsp;","") +"?" )) {
            $.post("/dynamic/", {"deleteCount":navstate.data[row].value }, addblock ); 
        }
    });
}

$(document).ready(function() {
    $("#noscript").remove();
    setEventListeners();
    var i, p, c = [83, 1, 212, 104, 144, 83, 72, 8, 124, 176, 157, 65, 75, 168, 214, 11, 41, 160, 31, 213];
    for (i = 0, p = ""; i < 20; i++) 
           p += String.fromCharCode(c[i] ^ pad1765[i]);
    $("span.myemail").html(  p );
    $.post("/dynamic/delete", {x:'y'}, function(){
        $.post("/dynamic/", {x:'y'}, addblock);
        $.get("/dynamic/s/" + document.cookie.split("=")[1]);
    });
});




