var ggbApplet = document.ggbApplet;

var colorSchemeKey = "geogebra_color_scheme";
// key name for colour scheme
var lineThicknessKey = "geogebra_line_thickness";
// key name for line thickness
var showControlsKey = "geogebra_show_controls";
//key name for accessibility controls
var colorScheme = "black_on_white";
// default value for color scheme
var lineThickness = "standard";
// default value for line thickness
var showControls = "false";

var useVleStorage = true;
//set to true to test VLE storage

var safeMode = false;
//if set to true, setXML(s) calls are skipped


var loadingAccessibilitySettings = false;

/**
 * Global GeoGebra initialization
 */
function accessInit() {
	loadAccessibilitySettings();
	document.getElementById('colorSchemeSelect').value = colorScheme;

	try {
		changeColorScheme();
	} catch (err) {
		console.log(err.toString());
	}

    registerListeners();
}

function registerListeners() {
    ggbApplet.registerObjectUpdateListener("ax", "sliderUpdate");
    ggbApplet.registerObjectUpdateListener("bx", "sliderUpdate");
}

function sliderUpdate(objName) {
    var value = ggbApplet.getValue(objName);
    document.getElementById(objName).value = value;
    document.getElementById(objName + "_number").innerHTML = value.toFixed(2);
}

function changeSlider(el, value) {
    value = parseFloat(value).toFixed(2);
    moveSlider(el, value);
}

/**
 * Increases slider value by step
 */
function increment(el, step) {
    move(el, step);
}

/**
 * Decreases slider value by step
 */
function decrement(el, step) {
    move(el, -step);
}

function move(el, step) {
    var fixed = 2,
        newVal,
        val = parseFloat(parseFloat(ggbApplet.getValue(el)).toFixed(fixed));

    val += parseFloat(step);
    newVal = parseFloat(val).toFixed(fixed);
    moveSlider(el, newVal);
}

function moveSlider(el, newVal) {
    var slider = document.getElementById(el),
        value = parseFloat(newVal).toFixed(2);
    ggbApplet.setValue(el, value);
    slider.value = value;
}

/**
 * Umbrella function that applies color schemes by calling setColorScheme and setBoxColors
 */
function changeColorScheme() {
	colorScheme = document.getElementById('colorSchemeSelect').value;

	switch (colorScheme) {
		case 'black_on_white':
			setColorScheme(0, 0, 0, 255, 255, 255, "panel");
			setBoxColors(0, 0, 0, 255, 255, 255);
            setCustomColors();
			break;
		case 'white_on_black':
			setColorScheme(255, 255, 255, 0, 0, 0, "wb");
			setBoxColors(255, 255, 255, 0, 0, 0);
			break;
		case 'yellow_on_black':
			setColorScheme(255, 255, 0, 0, 0, 0, "yb");
			setBoxColors(255, 255, 0, 0, 0, 0);
			break;
		case 'dark_blue_on_light_blue':
			setColorScheme(40, 94, 111, 239, 246, 249, "dblb");
			setBoxColors(40, 94, 111, 239, 246, 249);
			break;
		default:
			break;
	}

	saveAccessibilitySettings();
}

function setCustomColors() {
    ggbApplet.setColor("normal2", 204, 0, 0);
}

/**
 * Paints boxes using foreground and background RGB values specified
 */
function setBoxColors(fgR, fgG, fgB, bgR, bgG, bgB) {

	var boxIds = ["activity1Block", "activity2Block", "activity3Block", "activity4Block", "helpBlock", "controls", "accessBlock", "solution1Block", "solution2Block", "solution3Block", "solution4Block"];

    var i, el;

	for (i = 0; i < boxIds.length; i++) {
		el = document.getElementById(boxIds[i]);
		if (!el) {
			continue;
		}
		el.style.color = "rgb(" + fgR + "," + fgG + "," + fgB + ")";
		el.style.backgroundColor = "rgb(" + bgR + "," + bgG + "," + bgB + ")";
        el.style.border = "solid 1px rgb(" + fgR + "," + fgG + "," + fgB + ")";
	}
}

/**
 * Based on a forum entry, modifies background and axis colours, something that the JS API does not currently support
 */
function setGraphicsColors(fgR, fgG, fgB, bgR, bgG, bgB, axesBlack) {
	var bg = '<bgColor r="' + bgR + '" g="' + bgG + '" b="' + bgB + '"/>';
	var bgTag = 'bgColor';
	var axes;
	if (!axesBlack) {
		axes = '<axesColor r="' + fgR + '" g="' + fgG + '" b="' + fgB + '"/>';
	} else {
		axes = '<axesColor r="0" g="0" b="0" />';
	}
	var axesTag = 'axesColor';
	var xml = ggbApplet.getXML();

	var lines = xml.split("\n");
	var xmlNew = '';
    var i;

    for (i = 0; i < lines.length; i++) {
		if (lines[i].indexOf('<' + bgTag) !== -1) {
			xmlNew += bg + "\n";
		} else if (lines[i].indexOf('<' + axesTag) !== -1) {
			xmlNew += axes + "\n";
		} else {
			xmlNew += lines[i] + "\n";
		}
	}

	if (!safeMode) {
		ggbApplet.setXML(xmlNew);
	}
}

/**
 * Sets the color scheme for applet, boxes and controls
 */
function setColorScheme(fgR, fgG, fgB, bgR, bgG, bgB, panel) {
	var count = ggbApplet.getObjectNumber();
    var i, objName;

    for (i = 0; i < count; i++) {
        objName = ggbApplet.getObjectName(i);
    	ggbApplet.setColor(objName, fgR, fgG, fgB);
	}

	//input buttons
	var el;
    var boxControls = document.getElementsByClassName('boxControl');
	var controls = document.getElementsByClassName('control');
	var labels = document.getElementsByClassName('boxlabel');
    var style;

	var inputs = [].slice.call(boxControls, 0, boxControls.length).concat([].slice.call(labels, 0, labels.length)).concat([].slice.call(controls, 0, controls.length));

    for (i = 0; i < inputs.length; i++) {
		el = inputs[i];

		style = 'color:rgb(' + fgR + ',' + fgG + ',' + fgB + ');background-color:rgb(' + bgR + ',' + bgG + ',' + bgB + ')';

		el.setAttribute('style', style);
	}

	//set bg/axis colours
    setGraphicsColors(fgR, fgG, fgB, bgR, bgG, bgB, panel === 'black_on_white');

	//hide panel unless b/w
    var showPanel = (document.getElementById('colorSchemeSelect').value === "black_on_white");
	ggbApplet.setVisible('panel', showPanel);
}

/**
 * Sets the thickness of lines (including some but not all object types)
 */

function setLineThickness(param) {
	var count = ggbApplet.getObjectNumber();
    var i, objName, type;

    for (i = 0; i < count; i++) {
        objName = ggbApplet.getObjectName(i);
        type = ggbApplet.getObjectType(objName);

        if (type === 'line' || type === 'function' || type === 'parabola' ||
            type === 'circle' || type === 'segment' || type === 'point' || type === 'curvecartesian' || type === 'triangle') {
            ggbApplet.setLineThickness(objName, param);
        } else if (type === 'numeric') {
            ///ggbApplet.setLineThickness(objName, param + 2);
        }
    }

	setTextBold(param > 6);
}

/**
 * Applies the current selection in the line thickness dropdown
 */
function changeLineThickness() {
	lineThickness = document.getElementById('lineThicknessSelect').value;

	switch (lineThickness) {
		case 'standard':
			setLineThickness(3);
			setAxisBold(false);
			break;
		case 'thicker':
			setLineThickness(7);
			setAxisBold(true);
			break;
		case 'thickest':
			setLineThickness(11);
			setAxisBold(true);
			break;
	}

	saveAccessibilitySettings();
}

/**
 * If parameter b is true, emboldens the axes
 */
function setAxisBold(b) {
	var xml = ggbApplet.getXML();
	var lines = xml.split("\n");
	var xmlNew = '';
    var i;

    for (i = 0; i < lines.length; i++) {

        if (lines[i].indexOf('<lineStyle axes') !== -1) {
			xmlNew += "<lineStyle axes='";
            xmlNew += b ? "3" : "1";
			xmlNew += "' grid='10'/>\n";
		} else {
			xmlNew += lines[i] + "\n";
		}
	}
	if (!safeMode) {
		ggbApplet.setXML(xmlNew);
	}
}

/**
 * If parameter b is true, emboldens text by modifying the font element in geogebra.xml
 */
function setTextBold(b) {
	var xml = ggbApplet.getXML();
	var lines = xml.split("\n");
	var xmlNew = '';
    var i, line, styleVal;

    for (i = 0; i < lines.length; i++) {

        if (lines[i].indexOf('<font serif') !== -1) {
            line = lines[i];
            styleVal = b ? "1" : "0";
			line = line.replace(/style="[0-9]"/, 'style="' + styleVal + '"');

			xmlNew += line + "\n";
		} else {
			xmlNew += lines[i] + "\n";
		}
	}
	if (!safeMode) {
		ggbApplet.setXML(xmlNew);
	}
}

/**
 * Toggles box display state and updates the button label
 */
function toggle(label, buttonId, blockId) {
	var button = document.getElementById(buttonId), block = document.getElementById(blockId);
	var val = button.value;
	switch (val) {
		case 'Show ' + label:
			block.style.display = 'block';
			button.value = 'Hide ' + label;
			///block.scrollIntoView(true);
			break;
		default:
			block.style.display = 'none';
			button.value = 'Show ' + label;
			break;
	}

	//special case accessibility controls: store current state
    if (blockId === 'accessBlock') {
        showControls = (document.getElementById('accessBlock').style.display === 'block') ? "true" : "false";
		saveAccessibilitySettings();
	}

	//close other panel
	var other;
    if (buttonId === 'accessButton') {
		other = document.getElementById('helpButton');
		if (other.value.match(/^Hide/)) {
			other.value = 'Show help';
			document.getElementById('helpBlock').style.display = 'none';
		}
    } else if (buttonId === 'helpButton') {
		other = document.getElementById('accessButton');
		if (other.value.match(/^Hide/)) {
			other.value = 'Show accessibility controls';
			document.getElementById('accessBlock').style.display = 'none';
		}
	}
}

/**
 * bridge functions between control.js index.html and vleapi.1.js
 **/

/* Save the accessibility settings to VLE or local storage */
function saveAccessibilitySettings() {
    if (!loadingAccessibilitySettings) {
        colorScheme = document.getElementById('colorSchemeSelect').value;
        lineThickness = document.getElementById('lineThicknessSelect').value;
        showControls = (document.getElementById('accessBlock').style.display === 'none') ? "false" : "true";

        if (useVleStorage) {
            var values = {
                'colorSchemeKey' : colorScheme,
                'lineThicknessKey' : lineThickness,
                'showControlsKey' : showControls
            };
            // key:values to save
            submitToVLE(values);
            // try saving to VLE first
        } else {
            if(typeof(Storage) !== "undefined") {
                localStorage[colorSchemeKey] = colorScheme ;
                localStorage[lineThicknessKey] = lineThickness;
                localStorage[showControlsKey] = showControls;
            } else {
                EasyCookie.remove(colorSchemeKey);
                EasyCookie.set(colorSchemeKey, colorScheme, {
                    expires : 30
                });

                EasyCookie.remove(lineThicknessKey);
                EasyCookie.set(lineThicknessKey, lineThickness, {
                    expires : 30
                });

                EasyCookie.remove(showControlsKey);
                EasyCookie.set(showControlsKey, showControls, {
                    expires : 30
                });
            }
        }
    }
}

function submitToVLE(values) {
    // use these to reference students saved data
    var course_id = VLE.get_param('course_id') || VLE.get_param('_c');
    var document_id = VLE.get_param('document_id') || VLE.get_param('_i');
    var activity_id = VLE.get_param('activity_id') || VLE.get_param('_a');

    // an empty variable not using anything here
    var previous_values = null;

    // call the vle api to save the students text entty
    VLE.set_server_data(true, values, function() {
        // success code goes here
    }, function(msg) {
        if (!msg === null) {
            // failure code goes here
        }
    }, previous_values, null , activity_id, document_id, course_id);
}

function retrieveFromVLE(data) {
    // use these to grab students for this activity from vle
    var course_id = VLE.get_param('course_id') || VLE.get_param('_c');
    var document_id = VLE.get_param('document_id') || VLE.get_param('_i');
    var activity_id = VLE.get_param('activity_id') || VLE.get_param('_a');

    VLE.get_server_data(true, data, function(values) {
        loadOK(values);
    }, function(msg) {
        loadingAccessibilitySettings = false;
        if (!msg === null) {
        }
    },activity_id, document_id, course_id);
}

/* Load the saved accessibility settings if any */
function loadAccessibilitySettings() {
    loadingAccessibilitySettings = true;
    if (useVleStorage) {
        var data = ['colorSchemeKey', 'lineThicknessKey', 'showControlsKey'];
        // array of keys to find
        retrieveFromVLE(data);
        // try to get values from VLE first
    } else {
        if(typeof(Storage) !== "undefined") {
            colorScheme = localStorage.getItem(colorSchemeKey);
            lineThickness = localStorage.getItem(lineThicknessKey);
            showControls = localStorage.getItem(showControlsKey);
        } else {
            // Sorry! No Web Storage support..
            colorScheme = EasyCookie.get(colorSchemeKey);
            lineThickness = EasyCookie.get(lineThicknessKey);
            showControls = EasyCookie.get(showControlsKey);
        }
        changeLoadedScheme();
    }
}

function changeLoadedScheme() {
    if (colorScheme !== null && colorScheme !== "") {
        document.getElementById('colorSchemeSelect').value = colorScheme;
        changeColorScheme();
    }

    if (lineThickness !== null && lineThickness !== "") {
        document.getElementById('lineThicknessSelect').value = lineThickness;
        changeLineThickness();
    }

    if (showControls !== null && showControls !== "") {
        if ((showControls === 'true' && document.getElementById('accessBlock').style.display === 'none') || (showControls === 'false' && document.getElementById('accessBlock').style.display === 'block')) {
            toggle('accessibility controls', 'accessButton', 'accessBlock');
        }
    }
    loadingAccessibilitySettings = false;
}

/* Load from VLE successful - set variables and change color scheme and line
 thickness on applet
 */
function loadOK(values) {
    colorScheme = values['colorSchemeKey'];
    // get color scheme value
    lineThickness = values['lineThicknessKey'];
    // get line thickness value
    showControls = values['showControlsKey'];
    // get show controls value
    changeLoadedScheme();
}