/**
 * Disclaimer:
 * This is mostly old style event handlers and inline cross-browser
 * handling/checks for FF and IE. It's a rough version only intended
 * at this stage for demonstration. It is not expected to work in browsers
 * other than IE and FF due the the huge differences between browsers for
 * things like caret and mousewheel.
 *
 * If you're interested in using it, you're free to take the code and can drop
 * me an email - patrick@boundvariable.com - if you'd like me to clean it up.
 *
 */


timeInput = (function () {

    var ti,
        killDefault = function (e) {
            e.preventDefault();
        },
        // Pad checks the numerical range and zero pads to two characters
        pad = function (num, type) {
            if (type === "HH") {
                if (num < 0) {
                    return "12";
                } else if (num > 12) {
                    return "0";
                }
            } else if (type === "MM" || type === "SS") {
                if (num < 0) {
                    return "59";
        
                } else if (num > 59) {
                    return "00";
                }
            }
            if (num < 10) {
                num = "0" + num;
            }
            
            return num;
        },
    
        blocked = false,
    
        scrolled = function (ev) {
            var e = ev || window.event,
                ts = ti.value.split(/[:\s]/),
                hours = parseInt(ts[0], 10),       // split the value and get hours
                minutes = parseInt(ts[1], 10),     // minutes
                seconds = parseInt(ts[2], 10),     // seconds
                ampm = ts[3],                      // am or pm
                multiplier,
                selectionStart = ti.selectionStart,
                selectionEnd = ti.selectionEnd,
                scrollDelta = e.wheelDelta || e.detail, // wheelDelta for IE, detail otherwise
                range;
                
            if (blocked) {
                return;
            }
            
            // IE doesn't have selectionStart but we can get it
            // with the following createRange --> getBookmark --> charCodeAt trick
            // not just using guard because it may well be 0
            if (typeof selectionEnd === "undefined") {
                selectionEnd = document.selection.createRange().getBookmark().charCodeAt(2) - 2;
            }
            
            if (typeof selectionStart === "undefined") {
                selectionStart = selectionEnd; // we don't really care aabout the range here for IE
            }
            
            // Timeout to stop the jump-by-three issues that happens when the
            // input has mouseover
            window.setTimeout(function () {
                blocked = false;
            }, 30);
            
            blocked = true;
            
            
            
            // Directions +ve/-ve are reversed in FF compared to IE
            if (typeof e.detail !== "undefined") {
                if (scrollDelta > 0) {
                    multiplier = -1;
                } else {
                    multiplier = 1;
                }
            } else {    
                if (scrollDelta > 0) {
                    multiplier = 1;
                } else {
                    multiplier = -1;
                }
            }
            
            // Depending on the caret location we guess that the user
            // is trying to change different parts of the time
            switch(selectionEnd) {
                case 0:
                case 1:
                case 2:
                    selectionStart = 0;
                    selectionEnd = 2;
                    hours = hours + 1*multiplier;
                    break;    
                case 3:
                case 4:
                case 5:
                    selectionStart = 3;
                    selectionEnd = 5;
                    minutes = minutes + 1*multiplier;
                    break;
                case 6:
                case 7:
                case 8:
                    selectionStart = 6;
                    selectionEnd = 8;
                    seconds = seconds + 1*multiplier;
                    break;
                case 9:
                case 10:
                case 11:
                    selectionStart = 9;
                    selectionEnd = 11;
                    if (ampm.toLowerCase() === "am") {
                        ampm = "PM";
                    } else {
                        ampm = "AM";
                    }
                    break;
                default:
                    // nothing
            }
            
            

            hours = pad(hours, "HH");
            minutes = pad(minutes, "MM");
            seconds = pad(seconds, "SS");
            ti.value = hours + ":" + minutes + ":" + seconds + " " + ampm;
            
            
            // Changing the input value will move the caret
            // To get around this we reset the caret to
            // the time component the user is editing
            if (ti.setSelectionRange) {
                ti.setSelectionRange(selectionStart, selectionEnd);
            } else if (ti.createTextRange) {
               range = ti.createTextRange();
               range.collapse(true);
               range.moveEnd('character', selectionEnd);
               range.moveStart('character', selectionStart);
               range.select();
            }
            
            if (typeof e.preventDefault !== "undefined") {
                e.preventDefault();
                e.stopPropagation();
            }
            
            return false;
            
        },
        doTimeInput = function () {
            var bindTimeListener = function () {
                ti.onclick = null;
                
                if (document.addEventListener) {
                    document.addEventListener("DOMMouseScroll", scrolled, false);  // FF
                    window.addEventListener("DOMMouseScroll", killDefault, false);
                } else {
                    document.onmousewheel = scrolled;  // IE
                    window.onmousewheel = function() { return false; };
                }
            
                // and create a removalist
                ti.onblur = function () {
                    var ts,
                        hours,
                        minutes,
                        seconds,
                        ampm;
                    
                    ts = ti.value.split(/[:\s]/);
                    hours = pad(parseInt(ts[0], 10), "HH");
                    minutes = pad(parseInt(ts[1], 10), "MM");
                    seconds = pad(parseInt(ts[2], 10), "SS");
                    ampm = ts[3];
               
                    if (ampm.toLowerCase() !== "am" && ampm.toLowerCase() !== "pm") {
                        ampm = "AM";
                    }
                    
                    ti.value = hours + ":" + minutes + ":" + seconds + " " + ampm;
                    // If the user enters junk we just reset to 12:00:00 AM 
                    if (!/^[0-9]{2}:[0-9]{2}:[0-9]{2}\s(AM|PM|am|pm)$/.test(ti.value)) {
                        ti.value = "12:00:00 AM";
                    }
                    
                    ti.onclick = bindTimeListener;
                    if (document.removeEventListener) {
                        document.removeEventListener("DOMMouseScroll", scrolled, false);
                        window.removeEventListener("DOMMouseScroll", killDefault, false);
                    } else {
                        document.onmousewheel = null;
                        window.onmousewheel = null;
                    }
                };
            };
            
            ti = document.getElementById("time");
            
            ti.onclick = bindTimeListener;
        };
        
    
    return {
       setup: doTimeInput
    }

}());

var old = window.onload;
window.onload = function (e) {
    timeInput.setup();
    old(e);
};