﻿// Where to get the JSON file
var dataUrl = "data.txt";

// Questions to be presented to the user
var questions = [];

// Products by category, read from JSON data
var categories = [];

// Currently chosen parameters, arrays containing true or false
var chosenParams;
var chosenParamNames;
var chosenCategories;

// Products by category, to be sorted and displayed
var displayedCategories;

// Number of parameters, calculated from JSON
var maxParameter;

// Product chooser id, used for cookie name
var productChooserId;

// Startup

$(document).ready(function () {
    var result = $.parseJSON(json);
    init(result);
});

// Data received
	function init(result) {
	debug("Data received");

    // Get the questions and choices
    var jsonQuestions = result.metadata.questions;
    var jsonCategories = result.data;


    // Get product type and country
    var productType = result.metadata.producttype;
    var country = result.metadata.country;
    productChooserId = productType + "-" + country;


    // Store questions
    $.each(jsonQuestions, function(i, question) {
        questions.push(question);
    });

    // Store choices
    $.each(jsonCategories, function(i, category) {
        categories.push(category);
    });

    // Handle parameters
    maxParameter = questions.length - 1;
    for (var index = 0; index <= maxParameter; index++) {
        var questionName = questions[index].question;
        var param = $(categories[0].products[0]).attr(questionName);
        $("#parameters").append(createRadioControl(index));
        var paramName = questions[index].question;
        $("input[name=" + paramName + "]").click(paramsChanged, index);
    }

    // Handle categories
    $("#categories").append(createCategoryControl());
    $("input[name='category']").click(categoriesChanged);

    // Initialize other event handlers
    $("#button-showall").click(showAll);

    // Read the cookie with last settings for this product chooser
    var cookieText = readCookie(productChooserId);
    if (cookieText && cookieText.length > 0) {
        var cookie = $.parseJSON(cookieText);
        chosenParams = [];
        chosenParamNames = [];

        // Read all parameters
        for (var i = 0; i <= maxParameter; i++) {
            var paramName = questions[i].question;
            var values = cookie[i].values;
            var valueArray = [];
            var someSelected = false;
            var inputs = $("input[name=" + paramName + "]");
            $.each(values, function(j, value) {
                var v = value ? 1 : 0;
                valueArray.push(v);
                if (v == 1) {
                    inputs[j].checked = true;
                    someSelected = true;
                }
            });

            // None were selected, treat this as all were selected
            if (someSelected == false) {
                valueArray = [];
                $.each(values, function(j, value) {
                    valueArray.push(1);
                });
            }
            chosenParams.push(valueArray);
            chosenParamNames.push(paramName);
        }

        // Read all categories
        chosenCategories = [];
        for (var i = 0; i <= categories.length; i++) {
            var values = cookie[maxParameter + 1].values;
            var someSelected = false;
            var inputs = $("input[name='category']");
            $.each(values, function(j, value) {
                chosenCategories.push(value);
                if (value) {
                    inputs[j].checked = true;
                    someSelected = true;
                }
            });

            // None were selected, treat this as all were selected
            if (someSelected == false) {
                chosenCategories = [];
                $.each(values, function(j, value) {
                    chosenCategories.push(true);
                });
            }
        }
        filterAndSort();
        displayProducts();
    }
    else {
        showAll();
    }
    // Special case: No questions and only category
    if (categories.length == 1 && questions.length == 0) {
        $("#button-showall").hide();
    }
}

// Read a cookie
function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return decodeURI(c.substring(nameEQ.length, c.length));
    }
    return null;
}

// Save a cookie
function saveCookie() {
    var expires = "";
    var name = productChooserId;
    var value = "[";

    // Save parameters
    for (var i = 0; i <= maxParameter; i++) {
        var paramName = questions[i].question;
        value += '{"paramname":"' + paramName + '","values":[';
        var inputs = $("input[name=" + paramName + "]");
        var maxInput = $(inputs).length - 1;
        for (var j = 0; j <= maxInput; j++) {
            var selected = inputs[j].checked;
            value += selected;
            if (j < maxInput) {
                value += ",";
            }
        }
        value += "]},";
    }

    // Save categories
    value += '{"paramname":"categories","values":[';
    var inputs = $("input[name='category']");
    var maxInput = $(inputs).length - 1;
    for (var j = 0; j <= maxInput; j++) {
        var selected = inputs[j].checked;
        value += selected;
        if (j < maxInput) {
            value += ",";
        }
    }
    value += "]}]";
    document.cookie = name + "=" + encodeURI(value) + expires + "; path=/";
}

// Remove a cookie
function eraseCookie(name) {
    document.cookie = productChooserId + "=; path=/";
    var cookieText = readCookie(productChooserId);
}

// Create HTML for a radio button control
function createRadioControl(index) {
    var legend = questions[index].questiontext;
    var paramName = questions[index].question;
    var html = "<div class='parameter-title'>" + legend + "</div>";
    html += "<div class='control-container'><span id='control" + index + "'>";
    var values = $(categories[0].products[0]).attr(paramName);
    var prompts = questions[index].alternativetexts;
    $.each($(values), function(i, value) {
        html += "<label class='radio-control'><input type='radio' name='" + paramName + "' value='" + i + "' />";
        html += prompts[i] + "</label>";
    });
    html += "</span></div>";
    return html;
}

// Create HTML for a category checkbox control
function createCategoryControl() {
    var html = "<div class='parameter-title'>" + categoryLegend + "</div>";
    html += "<div id='left-column'>";
    var numCategories = categories.length;
    var rows = Math.ceil(numCategories / 2);
    $.each(categories, function(i, category) {
        if (i == rows) {
            html += "</div><div id='right-column'>";
        }
        html += "<div class='checkbox-container'><label class='checkbox-control'>";
        html += "<input type='checkbox' name='category' value='" + i + "' />";
        html += category.category + "</label></div>";
    });
    html += "</div>";
    // Hide categories if only one category
    if (categories.length == 1) {
        $("#category-container").hide();
    }
    return html;
}




// Show all products
function showAll() {
    for (var i = 0; i <= maxParameter; i++) {
        var paramName = questions[i].question;
        $("input[name=" + paramName + "]").removeAttr("checked");
    }
    $("input[name='category']").removeAttr("checked");
    selectAllParameters();
    filterAndSort();
    displayProducts();
    eraseCookie();
}

// Select all parameters
function selectAllParameters() {
    chosenParams = [];
    chosenParamNames = [];
    for (var i = 0; i <= maxParameter; i++) {
        var paramName = questions[i].question;
        var values = [];
        $.each($("input[name=" + paramName + "]"), function(i, value) {
            values.push(true);
        });
        chosenParams.push(values);
        chosenParamNames.push(paramName);
    }

    chosenCategories = [];
    $.each($("input[name='category']"), function(i, category) {
        chosenCategories.push(true);
    });
}

// Filter and sort products according to selection criteria
function filterAndSort() {
    displayedCategories = [];
    var candidates = [];

    // First select products according to category
    $.each(categories, function(i, category) {
        var categorySelected = chosenCategories[i];
        if (categorySelected) {
            candidates.push(category);
        }
    });

    // Candidates contains all products for the selected categories
    // Next, add the sorting weights according to selected parameters
    if (questions.length > 0) {
        $.each(candidates, function(i, category) {
            var hasProducts = false;
            $.each(category.products, function(j, product) {

                // Check parameters
                var weightParam = [];
                $.each(chosenParams, function(p, param) {
                    var w = 0;
                    $.each(param, function(v, value) {
                        if (value) {
                            var paramName = chosenParamNames[p];
                            productWeight = $(product).attr(paramName)[v];
                            w += productWeight;
                        }
                    });
                    weightParam.push(w);
                });

                // Need at least one point in all parameter categories
                product.weight = 0;
                var hasParamWeight = true;
                $.each(weightParam, function(p, param) {
                    if (param == 0) {
                        hasParamWeight = false;
                    }
                });

                // If no questions, then ignore parameters
                if (questions.length == 0) {
                    hasParamWeight = true;
                }

                if (hasParamWeight) {
                    $.each(chosenParams, function(p, param) {
                        var paramName = chosenParamNames[p];
                        product.weight += weightParam[p];
                    });
                    hasProducts = true;
                }
            });

            // If this category has products, then display the category
            if (hasProducts) {
                var cat = new Object();
                cat.category = category.category;
                cat.products = [];
                $.each(category.products, function(j, product) {
                    if (product.weight > 0) {
                        cat.products.push(product);
                    }
                });
                displayedCategories.push(cat);
            }
        });
    }

    // No questions, display all candidates
    else {
        $.each(candidates, function(i, category) {
            var cat = new Object();
            cat.category = category.category;
            cat.products = [];
            $.each(category.products, function(j, product) {
                product.weight = 1;
                cat.products.push(product);
            });
            displayedCategories.push(cat);
        });
    }

    // Finally sort the products according to weight
    $.each(displayedCategories, function(i, category) {
        var prods = category.products;
        prods.sort(function(a, b) {
            var compA = a.weight;
            var compB = b.weight;
            return (compA > compB) ? -1 : (compA < compB) ? 1 : 0;
        });
    });
    saveCookie();
}


// Display products
function displayProducts() {
    var str = "";
    var emptyList = true;
    $.each(displayedCategories, function(i, category) {
        str += "<div class='categoryname'>" + category.category + "</div><div class='product-container'>";
        $.each(category.products, function(j, product) {
            if (product.weight > 0) {
                str += "<div class='productname'>";
                str += "<a href='" + product.url + "' ";
                str += " target='" + product.target+ "' ";
                str += " title='" + product.tooltip + "'>";
                /*
                if (product.weight > 6) {
                str += "*** ";
                }
                else if (product.weight > 4) {
                str += "**&nbsp; ";
                }
                else if (product.weight > 2) {
                str += "*&nbsp;&nbsp; ";
                }
                else  {
                str += "&nbsp;&nbsp;&nbsp; ";
                }
                */
                str += product.name + "</a></div>";
                emptyList = false;
            }
        });
        str += "</div>";
    });
    if (emptyList) {
        str = "<div id='empty-list'>" + emptyListMessage + "</div>";
    }
    $('#product-list').html(str);
}

// Parameters have changed
function paramsChanged(event) {
    var paramName = event.currentTarget.name;
    //var paramNumber = paramName.slice(- 1);
    var values = [];
    $.each($("input[name=" + paramName + "]"), function(i, param) {
        var selected = param.checked;
        values.push(selected);
    });
    var index = -1;
    for (var i = 0; i < chosenParamNames.length; i++) {
        if (chosenParamNames[i] == paramName) {
            index = i;
            break;
        }
    }
    if (index == -1) {
        debug("Error when looking for " + paramName);
    }
    else {
        chosenParams[index] = values;
        filterAndSort();
        displayProducts();
    }
}

// Categories have changed
function categoriesChanged() {
    chosenCategories = [];
    var selectAll = true;
    $.each($("input[name='category']"), function(i, category) {
        var selected = category.checked;
        chosenCategories.push(selected);
        if (selected) {
            selectAll = false;
        }
    });

    // If no checkboxes are checked, then interpret this as "all are selected"
    if (selectAll) {
        chosenCategories = [];
        $.each($("input[name='category']"), function(i, category) {
            chosenCategories.push(true);
        });
    }
    filterAndSort();
    displayProducts();
}

// Encodes the jaons string to utf8
function utf8encode(utftext) {
	var string = '';
	var i = 0;
	var c = c1 = c2 = 0;

	while (i < utftext.length) {
		c = utftext.charCodeAt(i);

		if (c < 128) {
			string += String.fromCharCode(c);
			i++;
		}
		else if ((c > 191) && (c < 224)) {
			c2 = utftext.charCodeAt(i + 1);
			string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
		}
		else {
			c2 = utftext.charCodeAt(i + 1);
			c3 = utftext.charCodeAt(i + 2);
			string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}
	}
	return string;
}; 

// Print debug info
function debug(msg) {
    //$('#debug').append(msg + "<br/>");
}

