﻿// Skapar en nedräkningstimer och uppdaterar den med angivet intervall.
// Element-IDn som kan användas: JSTimerDays, JSTimerHours, JSTimerMinuter, JSTimerSeconds
// Bilder som heter 0 - 9.gif på angiven sökväg
// path: relativ sökväg till mappen med sifferbilderna        
// interval: uppdateringsintervall i ms
// imgClassName: css-klassnamn för bilderna
function JSTimer(path, interval, imgClassName) {            
    var inst = this;
    
    // Förladdar en bild
    this.createImage = function(path, name) {
        var image = new Image();
        image.src = path + "/" + name;
        image.className = imgClassName;            
        return image;
    };
    
    // Startar timern med angivet datum som mål
    // år, månad (1-12), dag, timme, minut, sekund
    this.start = function(year, month, day, hh, mm, ss) {
        inst.targetYear = year;
        inst.targetMonth = Math.max(0, Math.min(11, month - 1));
        inst.targetDay = Math.max(1, Math.min(31, day));
        inst.targetHour = Math.max(0, Math.min(23, hh));
        inst.targetMinutes = Math.max(0, Math.min(59, mm));
        inst.targetSeconds = Math.max(0, Math.min(59, ss));        
        setTimeout(inst.updateCallback, inst.updateInterval);
    };
    
    // Anropas när tiden uppdateras
    this.updateCallback = function() {                        
        var now = new Date();
        //var diffMs = Math.max(0, inst.targetDate.getTime() - now.getTime());
        var diffMs = Math.max(0, Date.UTC(
            inst.targetYear,
            inst.targetMonth,
            inst.targetDay,
            inst.targetHour,
            inst.targetMinutes,   // Kompensera för tidsskillnaden   
            inst.targetSeconds) + (new Date().getTimezoneOffset() * 60000) - now.getTime());
        
        var totalDays = diffMs / (24 * 3600 * 1000);
        var days = parseInt(Math.floor(totalDays), 10);            
        var partialDay = parseFloat(Math.max(0, totalDays - days));
        var partialHours = 24 * partialDay;
        var hours = parseInt(Math.floor(partialHours), 10);            
        var partialMinutes = parseFloat(Math.max(0, partialHours - hours));
        var minutes = parseInt(Math.floor(partialMinutes * 60), 10);            
        var seconds = parseInt(Math.floor(parseFloat((partialMinutes * 60) - minutes) * 60), 10);            
        
        if (days != inst.lastDays) {
            inst.addImagesToElement(inst.imagesFromNumber(days, 0, days, new Number(days).toString().length, false), "JSTimerDays");
        }
        if (hours != inst.lastHours) {
            inst.addImagesToElement(inst.imagesFromNumber(hours, 0, 23, 2, false), "JSTimerHours");
        }
        if (minutes != inst.lastMinutes) {
            inst.addImagesToElement(inst.imagesFromNumber(minutes, 0, 59, 2, true), "JSTimerMinutes");
        }
        if (seconds != inst.lastSeconds) {
            inst.addImagesToElement(inst.imagesFromNumber(seconds, 0, 59, 2, true), "JSTimerSeconds");
        }
        
        inst.lastDays = days;
        inst.lastHours = hours;
        inst.lastMinutes = minutes;
        inst.lastSeconds = seconds;
        
        setTimeout(inst.updateCallback, inst.updateInterval);
    };
    
    // använder digits-arrayen för att konvertera ett nummer till motsvarande bilder
    // null returneras om numret inte går att konvertera till ett heltal        
    // en array med image-element returneras annars
    // number: talet som ska konverteras
    // minValue: minsta värde (får inte vara lägre än 0)
    // maxValue: högsta värde
    // numDigits: minsta antal tecken, om talet är för lågt läggs nollor till
    // red: true om det ska vara en röd siffra
    this.imagesFromNumber = function(number, minValue, maxValue, numDigits, red) {
        var theNumber = parseInt(number, 10);
        if (isNaN(theNumber)) {
            return null;
        }
        
        theNumber = Math.max(minValue, Math.min(maxValue, theNumber));
        var numStr = String(theNumber);
        var outputArray = [];
        for (var i = 0; i < numStr.length; i++) {
            var digit = parseInt(numStr.charAt(i), 10);
            if (!isNaN(digit)) {
                outputArray[i] = red ? inst.digits[digit].red : inst.digits[digit];
            }
        }
        
        // kolla längden och lägg till nollor
        if (outputArray.length < numDigits) {
            for (var i = 0; i < (numDigits - outputArray.length); i++) {
                outputArray.unshift(red ? inst.digits[0].red : inst.digits[0]);
            }
        }
        
        return outputArray;
    };
    
    // Lägger till bild-element i angivet element
    this.addImagesToElement = function(imagesArray, targetElementId) {
        var targetElement = document.getElementById(targetElementId);
        if (imagesArray !== null && targetElement !== null) {
            var oldLength = targetElement.childNodes.length;
            
            for (var i = 0; i < imagesArray.length; i++) {
                var image = imagesArray[i];
                var imageElement = document.createElement("img", true);
                imageElement.src = image.src;
                imageElement.className = image.className + String(i);                
                targetElement.appendChild(imageElement);
            }
            
            // Radera de första noderna
            var childsToBeRemoved = [];
            for (var i = 0; i < oldLength; i++) {                    
                childsToBeRemoved.push(targetElement.childNodes[i]);                    
            }
            
            for (var i = 0; i < childsToBeRemoved.length; i++) {
                var child = childsToBeRemoved[i];
                if (child !== null) {
                    targetElement.removeChild(child);
                }
            }                
        }
    };
    
    inst.imageHref = path;
    inst.digits = [];
    inst.digits[0] = inst.createImage(path, "0.png");
    inst.digits[0].red = inst.createImage(path, "0.png");
    inst.digits[1] = inst.createImage(path, "1.png");
    inst.digits[1].red = inst.createImage(path, "1.png");
    inst.digits[2] = inst.createImage(path, "2.png");
    inst.digits[2].red = inst.createImage(path, "2.png");
    inst.digits[3] = inst.createImage(path, "3.png");
    inst.digits[3].red = inst.createImage(path, "3.png");
    inst.digits[4] = inst.createImage(path, "4.png");
    inst.digits[4].red = inst.createImage(path, "4.png");
    inst.digits[5] = inst.createImage(path, "5.png");
    inst.digits[5].red = inst.createImage(path, "5.png");
    inst.digits[6] = inst.createImage(path, "6.png");
    inst.digits[6].red = inst.createImage(path, "6.png");
    inst.digits[7] = inst.createImage(path, "7.png");
    inst.digits[7].red = inst.createImage(path, "7.png");
    inst.digits[8] = inst.createImage(path, "8.png");
    inst.digits[8].red = inst.createImage(path, "8.png");
    inst.digits[9] = inst.createImage(path, "9.png");            
    inst.digits[9].red = inst.createImage(path, "9.png");            
    inst.updateInterval = Math.max(0, parseInt(interval, 10));
    inst.lastDays = inst.lastHours = inst.lastMinutes = inst.lastSeconds = -1;                
    if (isNaN(inst.updateInterval)) {
        inst.updateInterval = 500;
    }
}
