var skateCalculator = function() {
    // Different states
    var ENTER_TIME = 1;
    var SHOW_POINTS = 2;

    // Different buttons
    var NO_BUTTON       = 0;
    var BUTTON_EQUALS   = 1;
    var BUTTON_DISTANCE = 2;

    var _pointsInMempory = 0.0;
    var _currentPoints = 0.0;
    var _timeInput = "";
    var _dot1Index = 0;
    var _dot2Index = 0;
    var _numberOfDots = 0;
    var _currentState = ENTER_TIME;
    var _lastButtonClicked = NO_BUTTON;

    return {
        helpClick : function () {
            dijit.byId('skate_calculator_help').show();
        },

        points2string : function (flPoints) {
            // Schaatspunten worden afgekapt op 3 cijfers achter de komma
            var strNum = flPoints.toString();
            var i = strNum.indexOf(".");
            if (i === -1) {
                strNum += ".000";
            } else {
                while ((strNum.length - (i+1)) < 3) {
                    strNum += "0";
                }

                if ((strNum.length - (i+1)) > 3) {
                    strNum = strNum.substring(0,i+4);
                }
            }
            return strNum;
        },

        dspClick : function () {
            document.skatecalc.dsp.select();
        },

        clearAll : function () {
            _timeInput = "";
            document.skatecalc.dsp.value = "0";
            _pointsInMempory = 0.0;
            _currentPoints = 0.0;
            _dot1Index = 0;
            _dot2Index = 0;
            _numberOfDots = 0;
            _currentState = ENTER_TIME;
            _lastButtonClicked = NO_BUTTON;
            document.skatecalc.dsp.focus();
        },

        clearEntry : function () {
            if (_currentState === ENTER_TIME) {
                _timeInput = "";
                document.skatecalc.dsp.value = "0";
                _dot1Index = 0;
                _dot2Index = 0;
                _numberOfDots = 0;
            }
            if (_lastButtonClicked !== NO_BUTTON) {
                this.clearAll();
            }
        },

        time2seconds : function () {
            // Deze functie berekent de ingevoerde tijd in seconden
            var minutes = 0;
            var seconds = 0;
            var sseconds = 0;
            var strSs = "0";

            switch (_numberOfDots) {
                case 0:
                    // Input bevat alleen seconden: SS
                    minutes = 0;
                    if (_timeInput !== "") seconds = parseInt(this.leftZeroTrim(_timeInput), 10);
                    strSs = "00";
                    break;
                case 1:
                    // Input bevat alleen seconden en cijfers achter de komma: SS.ss
                    minutes = 0;
                    seconds = parseInt(this.leftZeroTrim(_timeInput.substring(0,_dot1Index)), 10);
                    strSs = _timeInput.substring(_dot1Index+1);
                    break;
                case 2:
                    // Input bevat minuten, seconden en cijfers achter de komma: MM.SS.ss
                    minutes = parseInt(this.leftZeroTrim(_timeInput.substring(0,_dot1Index)), 10);
                    seconds = parseInt(this.leftZeroTrim(_timeInput.substring(_dot1Index+1,_dot2Index)), 10);
                    strSs = _timeInput.substring(_dot2Index+1);
                    break;
                default:
                    break;
            }

            strSs = (strSs.length < 2) ? strSs + "0" : strSs;
            sseconds = parseInt(this.leftZeroTrim(strSs), 10);
            return ((minutes * 60.0) + (seconds * 1.0) + (sseconds / 100.0));
        },

        leftZeroTrim : function (sString) {
            while (sString.substring(0,1) === '0' && sString.length > 1) {
                sString = sString.substring(1, sString.length);
            }
            return sString;
        },

        numClick : function (number) {
            // De input (tijd) kan maximaal 8 karakters lang zijn (inclusief punten): MM.SS.ss
            // Voorloopnullen doen we niet aan, alleen tijden in de vorm van bijvoorbeeld 0.11
            // Het 1e cijfer na de 1e punt mag niet groter zijn dan 5 (zie periodClick)
            // Voor de 1e punt mogen maximaal 2 cijfers staan
            // Na een punt mogen maxmaal 2 cijfers staan
            // Tussen de 1e en 2e punt moeten precies 2 cijfers staan

            if (_currentState === SHOW_POINTS && _lastButtonClicked !== NO_BUTTON) {
                // De gebruiker begin weer aan een nieuwe time-entry
                this.clearAll();
            }

            if (_currentState === ENTER_TIME && _timeInput.length < 9 && (_timeInput.length > 0 || number > '0')) {
                if (_timeInput.length < 2 && _numberOfDots === 0) {
                    // Als het goed is, is er nog geen punt ingevoerd
                    _timeInput += number;
                } else {
                    if ((_timeInput.length - (_dot1Index+1)) < 2 && _numberOfDots === 1) {
                        _timeInput += number;
                    } else {
                        if ((_timeInput.length - (_dot2Index+1)) < 2 && _numberOfDots === 2) {
                            _timeInput += number;
                        }
                    }
                }
                document.skatecalc.dsp.value = _timeInput.substring(0,_timeInput.length);
            } else {
                document.skatecalc.dsp.value = "0";
            }
        },

        plusClick : function () {
            if (_currentState === SHOW_POINTS) {
                _pointsInMempory += _currentPoints;
                var tmpPoints = _pointsInMempory;
                this.clearAll();
                _pointsInMempory = tmpPoints;
                document.skatecalc.dsp.value = this.points2string(_pointsInMempory);
            }
        },

        equalClick : function () {
            if (_currentState === SHOW_POINTS) {
                _lastButtonClicked = BUTTON_EQUALS;

                _pointsInMempory += _currentPoints;
                _currentPoints = 0.0;
                _timeInput = "";
                _dot1Index = 0;
                _dot2Index = 0;
                _numberOfDots = 0;

                document.skatecalc.dsp.value = this.points2string(_pointsInMempory);
            }
        },

        periodClick : function () {
            if (_currentState === ENTER_TIME) {
                if (_timeInput.length === 0) {
                    _dot1Index = 1;
                    _timeInput = "0.";
                    _numberOfDots = 1;
                } else {
                    if ((_timeInput.length === 1 || _timeInput.length === 2) && (_numberOfDots === 0)) {
                        _dot1Index = _timeInput.length;
                        _timeInput += ".";
                        _numberOfDots = 1;
                    } else {
                        // Na de eerste punt moeten 2 cijfers staan, en het
                        // 1e cijfer na de 1e punt mag niet groter zijn dan 5

                        if (_numberOfDots === 1 && (_timeInput.length - (_dot1Index+1)) === 2 && _timeInput.charAt(_dot1Index+1) < '6') {
                            _dot2Index = _timeInput.length;
                            _timeInput += ".";
                            _numberOfDots = 2;
                        }
                    }
                }
                document.skatecalc.dsp.value = _timeInput.substring(0,_timeInput.length);
            }
        },

        dstClick : function (distance) {
            if (_currentState === ENTER_TIME) {
                _currentState = SHOW_POINTS;
                _lastButtonClicked = BUTTON_DISTANCE;
                _currentPoints = (this.time2seconds(_timeInput) * 500.0) / distance;
                document.skatecalc.dsp.value = this.points2string(_currentPoints);
            }
        },

        bckspcClick : function () {
            if (_currentState === ENTER_TIME) {
                if (_timeInput.length > 0) {
                    // Bij het verwijderen van een punt moeten we iets extra's doen
                    if (_numberOfDots > 0 && _timeInput.charAt(_timeInput.length-1) === '.') {
                        if (_numberOfDots === 2) {
                            _dot2Index = 0;
                        } else {
                            _dot1Index = 0;
                        }
                        _numberOfDots--;
                    }
                    _timeInput = _timeInput.substring(0,_timeInput.length-1);
                }
                if (_timeInput.length === 0) {
                    _timeInput = "";
                    document.skatecalc.dsp.value = 0;
                } else {
                    document.skatecalc.dsp.value = _timeInput;
                }
            }
        },

        change_style : function (buttonRef,toClassName) {
            var currClassName = buttonRef.getAttribute("className");
            buttonRef.className = toClassName;
        },

        // <input type="text" onkeypress="return handleKey(event)" />
        handleKey : function (e) {
            var keynum;
            var keychar;

            if(window.event)  {
                // IE
                keynum = e.keyCode;
            } else if(e.which) {
                // Netscape/Firefox/Opera
                keynum = e.which;
            }
            keychar = String.fromCharCode(keynum);
            switch (keychar) {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                	this.numClick(keychar);
                    return true;
                case '+':
                	this.plusClick();
                    return true;
                case '=':
                    this.equalClick();
                    return true;
                case '?':
                    this.helpClick();
                    return true;
                case '.':
                	this.periodClick();
                    return true;
                case 'c':
                case 'C':
                    this.clearAll();
                    return true;
                case '<':
                    this.bckspcClick();
                    return true;
                default:
                    return false;
            }
            return false;
        }
    };
}();
