/**
 * 
 * 
 * Objekt: LED()
 * Autor: J. Strübig
 * 
 * Version 0.5 / Datum: 18.11.2011 - 21:11
 * -Code komplett neu geschrieben, mehr objektorientiert
 * 
 * Version 0.4 / Datum: 11:25 22.06.2010
 * - Parameter von Konstruktor und .create() vertauscht
 *  -Feinarbeiten
 *  -scrollOut() Funktion
 * 
 * Version 0.3 / Datum: 11:25 15.02.2009
 *  -Vererbung über prototype
 * 
 * Version 0.2 / Datum: 11:24 14.02.2009
 * - erste Version
 * 
 * Methoden:
 * 
 * seText(string)
 * charAt(top, left, char)
 * print(string)
 * set(top, left on/off)
 * 
 * stop()
 * start()
 * 
 * pause(millisekunden)
 * up(anzahl)
 * blink(anzahl)
 * flash(anzahl)
 * scrollOut() 
 * 
 * clear(vordergrund, hintergrund)
 * copy(LED)
 * 
 * Eigenschaften LED.cfg
 * 
 * blinkInterval
 * blinkAmount
 * scrollAmount
 * scrollSpeed
 * pause_ms
 * 
 * */

var LED = function(h, w, px, pad) {

	var bitmap = LED.charset.set;
	if(h < LED.charset.height) h  = LED.charset.height;

	this.cfg = {
        speed: 100,
        blinkInterval: 350,
        blinkAmount: 3,
        scrollAmount: 1,
        scrollSpeed: 150,
        pause_ms: 500
    };
	
	// local
	var 
    messageArray,
    columnPointer, // für die Scrollfunktion
    char_offset,
    cursor = 0, // für print/charAt
    doScroll = false,
    stop = false, // Flag um Aktionen stoppen zu können
    _this = this,
    panel = null;
    
    var action = function(func, time, count, repeat) {

        var local_count;
        if(!repeat) repeat = 1;

        stop = false; // Trigger
        doScroll = false; // scrollen stoppen
        
        function outer_loop() {
            local_count = count;
            if(repeat--) inner_loop();
            else end();
        }
        function inner_loop() {
            func();
            if(--local_count) window.setTimeout(inner_loop, time);
            else outer_loop();
        }

        function end() {
            doScroll = !doScroll;
            if(!stop && doScroll) window.setTimeout(scroll, time);
            stop = true;
        }
        window.setTimeout(outer_loop, time);
    };
    var scroll = function() {
		// Textausgabe
		var temp = messageArray[columnPointer++];
		if(columnPointer == messageArray.length) columnPointer = 0;

		if(isNaN(temp)) {
			// Sonderzeichen
			switch(temp.substr(0, 1)) {
				case '#': _this.blink(temp.substring(1)); break;
				case '^': _this.up(temp.substring(1)); break;
				case '_': _this.flash(temp.substring(1)); break;
				case '@': _this.pause(temp.substring(1)); break;
                case '*': _this.scrollOut(); break;
                case '$': _this.stop(); break;

			}
		} else {
			panel.scrollLeft();
			panel.setByte(panel.width() - 1, temp);
		}

		if(doScroll)window.setTimeout(scroll, _this.cfg.speed);
	}

    
    this.clear = function(a, b){
        cursor = 0;
        return panel.clear(a, b);
    }
    this.create = function(p) {
        return panel.create(p);
    };
    this.copy = function(p) {
        return panel.copy(p);
    };
    this.set = function(a,b,c) {
        return panel.set(a,b,c);
    };
    
	this.start = function() {
		if(!stop) return;
		doScroll = true;
		stop = true;
		scroll();
	};
	this.stop = function() {
		doScroll = false;
		stop = true;
	};

	this.pause = function(c) {
		action(function() {}, c || this.cfg.pause_ms);
	};

	this.up = function(loop) {
		if(!loop) loop = this.cfg.scrollAmount;
        
        action(
        function() {
            panel.scrollUp(true);
        }, this.cfg.scrollSpeed, panel.height(), loop);
        
	};
	this.blink = function(c) {
		var on = panel.dots(true);
		if(!c) c = this.cfg.blinkAmount;
		action(
        function() {
				for(var i = 0; i < on.length; ++i) on[i].toogle();
		}, _this.cfg.blinkInterval, c * 2);
	};
	this.flash = function(c) {
		var on = panel.dots(false);
		if(!c) c = this.cfg.blinkAmount;
		action(
        function() {
			for(var i = 0; i < on.length; ++i) on[i].flash();
		}, _this.cfg.blinkInterval, c * 2);
	};
	this.scrollOut = function() {
		var w = this.panel.width() ;
		action(
        function() {
				_this.panel.scrollLeft();
		}, this.cfg.speed, w);
    }
    
	this.charAt = function(t, l, char) {
		if(!t || t < 0) t = 0;
		if(!l || l < 0) l = 0;
		
        c = bitmap[char.toUpperCase()];
        if(!c) return;
        
		var off = char_offset - t;

		if(off < 0) off = 0;
		for(var i = 0; i < c.length; i++) {
			var tmp = c[i] << off;

			panel.setByte(l + i, tmp, char);
			++cursor;
		}
		++cursor;
		if(cursor > panel.width()) cursor = 0;
	};

	this.print = function(txt) {
		for(var i = 0; i < txt.length; ++i) {
			this.charAt(0, cursor, txt.substr(i, 1));
		}
	};
    
	this.setText = function(txt) {
		if(typeof txt == 'undefined' || !txt.length) return;
		this.stop();
		char_offset = parseInt(((panel.height() - LED.charset.height) / 2));
		var text = txt.toUpperCase();
		messageArray = [];
		for (var i = 0; i < text.length; ++i){
            var c = text.substr(i, 1);
			var letter = bitmap[c];
   			
            if(!letter) {
				// Sonderfunktionen.
				// Die Zahl in einer geschweiften Klammer dahinter, wird der zugehörigen Funktion übergeben
				var zahl = '';
				var k1 = text.indexOf('{', i) + 1;
				var k2 = text.indexOf('}', i);
				if(k1 && k1 - i == 2) { zahl = text.substring(k1, k2); i += k2 - k1 + 2;} 
                //zahl = +text.substring(i+1);
                
				messageArray.push(c + zahl); 
			} else  {
				// Das Bitmap-Array erzeugen
				for (var j = 0; j < letter.length; ++j) messageArray.push(letter[j] << char_offset);
				messageArray.push(0); // Abstand zwischen Buchstaben
			}
		}
        
		columnPointer = 0;
	};

    panel = new LED.Panel({
        height: h,
        width: w,
        pixel: px,
        padding: pad
    });
    
    this.panel  = panel;
    this.setText(' ');
    function event(e)  {
        e.led = _this;
    }
    panel.click(event);
}

LED.flashBackground = '#fff';
LED.backgroundColor = '#000';

