/*!
 * jQuery JavaScript ledSimulator Plugin v1.0
 *
 * Copyright 2011, Stephan Schröter
 *
 */

(function( $ ){

    var methods = {
        
        init : function( options ) {
            
            var settings = {}
            
            return this.each(function(){
                
                if ( options ) {
                    $.extend( settings, options );
                }
                
                var obj = $(this);
                
                obj
                    .data('length',settings.ledLengthDefault)
                    .data('color',settings.ledColorDefault)
                    .data('effect',settings.ledEffectDefault)
                    .data('timer', false)
                ;
                
                obj
                    .data('autoPlayInterval',1000)
                    .data('autoPlayState','init')
                ;
                
                obj.ledSimulator('generateSimulator', settings);
                obj.ledSimulator('setLedLength', settings);
                obj.ledSimulator('setLedColor', settings);
                obj.ledSimulator('setLedEffect', settings);
                obj.ledSimulator('setReset', settings);
                obj.ledSimulator('handleLedLength', settings);
                obj.ledSimulator('handleLedColor', settings);
                obj.ledSimulator('handleLedEffect', settings);
                obj.ledSimulator('handleReset', settings);
                obj.ledSimulator('handleAutoPlay', settings);
                /*obj.ledSimulator('setAutoPlayInterval', settings);*/
                
                
                
                
            });
            
        },
        
        // handleAutoPlay
        handleAutoPlay : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                clearInterval( obj.data('timer') );
                
                if (obj.data('autoPlayState') == 'init') {
                    
                    obj
                        .find('span.led > span')
                        .animate({'width':''+ settings.ledWidth +'px'}, obj.data('autoPlayInterval')/2 )
                        .fadeTo(obj.data('autoPlayInterval')/2,0)
                    ;
                    
                    obj
                        .data('autoPlayState','running')
                    ;
                
                } else {
                    
                    obj.ledSimulator('setAutoPlayInterval', settings);
                    
                }
                
                obj
                    .data(
                        'timer', 
                        setInterval (function() {obj.ledSimulator('handleTransition', settings)}, obj.data('autoPlayInterval') )
                    )
                ;
                
                
            });
            
        },
        
        // setAutoPlayInterval
        setAutoPlayInterval : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                if (obj.data('effect') == 'sequential') {
                    
                    obj
                        .data('autoPlayInterval', settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)] * (parseInt(obj.data('length'))) + settings.ledEffectDelay[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                    ;
                    
                }
                
                if (obj.data('effect') == 'flash') {
                    
                    obj
                        .data('autoPlayInterval', settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)] + settings.ledEffectDelay[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                    ;
                    
                }
                
                if (obj.data('effect') == 'sweller') {
                    
                    obj
                        .data('autoPlayInterval', settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)] + settings.ledEffectDelay[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                    ;
                    
                }
                
                if (obj.data('effect') == 'bottom-up') {
                    
                    obj
                        .data('autoPlayInterval', settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)] * (parseInt(obj.data('length'))+1) + settings.ledEffectDelay[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                    ;
                    
                }
                
                if (obj.data('effect') == 'random') {
                    
                    obj
                        .data('autoPlayInterval', settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)] + settings.ledEffectDelay[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                    ;
                    
                }
                
                
            });
            
        },
        
        // handleTransition
        handleTransition : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj.ledSimulator('handleAutoPlay', settings);
                
                
                if (obj.data('effect') == 'sequential') {
                    
                    obj
                        .find('span.led > span')
                        .stop(true, true, true)
                        .fadeTo(0,0)
                    ;
                    
                    obj
                        .children('span.led')
                        .each(function(index){
                            
                            if (index < obj.data('length')) {
                                
                                $(this)
                                    .children('span')
                                    .fadeTo(0,1)
                                    .parent()
                                    .parent()
                                    .find('span.led > span')
                                    .animate({'width':''+ settings.ledWidth +'px'},settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)])
                                    .fadeTo(0,0)
                                ;
                                
                            }
                            
                        })
                    ;
                    
                    
                }
                
                if (obj.data('effect') == 'flash') {
                    
                    obj
                        .find('span.led > span')
                        .stop(true, true, true)
                        .fadeTo(0,0)
                    ;
                    
                    obj
                        .children('span.led')
                        .each(function(index){
                            
                            if (index < obj.data('length')) {
                                
                                $(this)
                                    .children('span')
                                    .fadeTo(0,1)
                                    .animate({'width':''+ settings.ledWidth +'px'},settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)])
                                    .fadeTo(0,0)
                                ;
                                
                            }
                            
                        })
                    ;
                    
                }
                
                if (obj.data('effect') == 'sweller') {
                    
                    obj
                        .find('span.led > span')
                        .stop(true, true, true)
                        .fadeTo(0,0)
                    ;
                    
                    obj
                        .children('span.led')
                        .each(function(index){
                            
                            if (index < obj.data('length')) {
                                
                                $(this)
                                    .children('span')
                                    .fadeTo(settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)]/2,1)
                                    .fadeTo(settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)]/2,0)
                                ;
                                
                            }
                            
                        })
                    ;
                    
                }
                
                if (obj.data('effect') == 'bottom-up') {
                    
                    obj
                        .find('span.led > span')
                        .stop(true, true, true)
                        .fadeTo(0,0)
                    ;
                    
                    obj
                        .children('span.led')
                        .each(function(index){
                            
                            if (index < obj.data('length')) {
                                
                                $(this)
                                    .children('span')
                                    .fadeTo(0,1)
                                    .parent()
                                    .parent()
                                    .find('span.led > span')
                                    .animate({'width':''+ settings.ledWidth +'px'},settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)])
                                    
                                ;
                                
                            }
                            
                        })
                    ;
                    
                    obj
                        .find('span.led > span')
                        .fadeTo(settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)],0)
                    ;
                    
                }
                
                if (obj.data('effect') == 'random') {
                    
                    obj
                        .find('span.led > span')
                        .stop(true, true, true)
                        .fadeTo(0,0)
                    ;
                    
                    obj
                        .children('span.led')
                        .eq( Math.floor(Math.random()*obj.data('length')) )
                        .children('span')
                        .fadeTo(0,1)
                        .animate({'width':''+ settings.ledWidth +'px'},settings.ledEffectBeVisible[$.inArray(obj.data('effect'),settings.ledEffectCode)])
                        .fadeTo(0,0)
                    ;
                    
                }
                
                
            });
            
        },
        
        // setLedLength
        setLedLength : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .children('ul.select')
                    .append(
                        '<li class="select-length"><span>'+ settings.ledLengthText +' (<span></span>)</span>'+
                            '<ul></ul>'+
                        '</li>'
                    )
                ;
                
                obj
                    .find('ul.select > li.select-length > span > span')
                    .text( settings.ledLength[$.inArray(obj.data('length'),settings.ledLengthCode)] )
                ;
                
                $.each(settings.ledLength, function(i) {
                    
                    obj
                        .find('ul.select > li.select-length > ul')
                        .append('<li>'+ settings.ledLength[i] +'</li>')
                    ;
                    
                });
                
                for (var i = 0; i < settings.ledLength.length; i++) {
                    
                    obj
                        .append('<span class="led"><span></span></span>')
                    ;
                    
                }
                
                var offsetLeft = ( settings.width - ( settings.ledLength.length * ( settings.ledWidth + settings.ledSpaceDefault ) ) ) / 2;
                var offsetTop = ( settings.height - settings.ledWidth ) / 2;
                
                obj
                    .children('span.led')
                    .each(function(index){
                        
                        $(this)
                            .css({
                                'top':''+ offsetTop +'px',
                                'left':''+ ( offsetLeft + ( index*settings.ledSpaceDefault + settings.ledSpaceDefault/2 ) + ( index*settings.ledWidth ) ) +'px'
                            })
                        ;
                        
                        if (index >= obj.data('length')) {
                            
                            $(this)
                                .hide()
                            ;
                            
                        }
                        
                    })
                ;
                
            });
            
        },
        
        // handleLedLength
        handleLedLength : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .children('span.led')
			        .draggable({
			        	containment: 'parent', 
			        	scroll: false,
			        	cursor: 'move'
			        })
			    ;
			    
			    obj
                    .find('ul.select > li.select-length')
                    .mouseenter(function(){
                        
                        $(this)
                            .children('ul')
                            .show()
                        ;
                        
                    })
                    .mouseleave(function(){
                        
                        $(this)
                            .children('ul')
                            .hide()
                        ;
                        
                    })
                ;
			    
			    obj
                    .find('ul.select > li.select-length > ul > li')
                    .click(function(){
                        
                        $(this)
                            .parent()
                            .hide()
                        ;
                        
                        obj
                            .data('length',settings.ledLengthCode[$.inArray($(this).text(),settings.ledLength)])
                        ;
                        
                        obj
                            .find('ul.select > li.select-length > span > span')
                            .text( settings.ledLength[$.inArray(obj.data('length'),settings.ledLengthCode)] )
                        ;
                        
                        obj
                            .children('span.led')
                            .show()
                            .each(function(index){
                                
                                if (index >= obj.data('length')) {
                                    
                                    $(this)
                                        .hide()
                                    ;
                                    
                                }
                                
                            })
                        ;
                        
                        obj.ledSimulator('handleTransition', settings);
                        
                        return false;
                        
                    })
                ;
                
            });
            
        },
        
        // setLedColor
        setLedColor : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .children('ul.select')
                    .append(
                        '<li class="select-color"><span>'+ settings.ledColorText +' (<span></span>)</span>'+
                            '<ul></ul>'+
                        '</li>'
                    )
                ;
                
                obj
                    .find('ul.select > li.select-color > span > span')
                    .text( settings.ledColor[$.inArray(obj.data('color'),settings.ledColorCode)] )
                ;
                
                $.each(settings.ledColor, function(i) {
                    
                    obj
                        .find('ul.select > li.select-color > ul')
                        .append('<li>'+ settings.ledColor[i] +'</li>')
                    ;
                    
                });
                
                obj
                    .children('span.led')
                    .children('span')
                    .css({
                        'background-position':'0 '+ obj.data('color') +''
                    })
                ;
                
                
            });
            
        },
        
        // handleLedColor
        handleLedColor : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .find('ul.select > li.select-color')
                    .mouseenter(function(){
                        
                        $(this)
                            .children('ul')
                            .show()
                        ;
                        
                    })
                    .mouseleave(function(){
                        
                        $(this)
                            .children('ul')
                            .hide()
                        ;
                        
                    })
                ;
                
                obj
                    .find('ul.select > li.select-color > ul > li')
                    .click(function(){
                        
                        $(this)
                            .parent()
                            .hide()
                        ;
                        
                        obj
                            .data('color',settings.ledColorCode[$.inArray($(this).text(),settings.ledColor)])
                        ;
                        
                        obj
                            .find('ul.select > li.select-color > span > span')
                            .text( settings.ledColor[$.inArray(obj.data('color'),settings.ledColorCode)] )
                        ;
                        
                        obj
                            .children('span.led')
                            .children('span')
                            .css({
                                'background-position':'0 '+ obj.data('color') +''
                            })
                        ;
                        
                        return false;
                        
                    })
                ;
                
                
            });
            
        },
        
        // setLedEffect
        setLedEffect : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .children('ul.select')
                    .append(
                        '<li class="select-effect"><span>'+ settings.ledEffectText +' (<span></span>)</span>'+
                            '<ul></ul>'+
                        '</li>'
                    )
                ;
                
                obj
                    .find('ul.select > li.select-effect > span > span')
                    .text( settings.ledEffect[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                ;
                
                $.each(settings.ledEffect, function(i) {
                    
                    obj
                        .find('ul.select > li.select-effect > ul')
                        .append('<li>'+ settings.ledEffect[i] +'</li>')
                    ;
                    
                });
                
                
            });
            
        },
        
        // handleLedEffect
        handleLedEffect : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .find('ul.select > li.select-effect')
                    .mouseenter(function(){
                        
                        $(this)
                            .children('ul')
                            .show()
                        ;
                        
                    })
                    .mouseleave(function(){
                        
                        $(this)
                            .children('ul')
                            .hide()
                        ;
                        
                    })
                ;
                
                obj
                    .find('ul.select > li.select-effect > ul > li')
                    .click(function(){
                        
                        $(this)
                            .parent()
                            .hide()
                        ;
                        
                        obj
                            .data('effect',settings.ledEffectCode[$.inArray($(this).text(),settings.ledEffect)])
                        ;
                        
                        obj
                            .find('ul.select > li.select-effect > span > span')
                            .text( settings.ledEffect[$.inArray(obj.data('effect'),settings.ledEffectCode)] )
                        ;
                        
                        obj.ledSimulator('handleTransition', settings);
                        
                        return false;
                        
                    })
                ;
                
                
            });
            
        },
        
        // setReset
        setReset : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .append('<span class="button reset">'+ settings.resetText +'</span>')
                ;
                
            });
            
        },
        
        // handleReset
        handleReset : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .children('span.reset')
                    .click(function(){
                        
                        clearInterval( obj.data('timer') );
                        
                        obj
                            .children()
                            .remove()
                        ;
                        
                        obj.ledSimulator('init', settings);
                        
                        return false;
                        
                    })
                ;
                
            });
            
        },
        
        // generateSimulator
        generateSimulator : function( settings ) {
            
            return this.each(function(){
                
                var obj = $(this);
                
                obj
                    .css({
                        'width':''+ settings.width +'px',
                        'height':''+ settings.height +'px',
                        'background-color': settings.bgColor
                    })
                ;
                
                obj
                    .append('<span class="info">'+ settings.infoText +'</span>')
                ;
                
                obj
                    .append('<ul class="select"></ul>')
                ;
                
                
            });
            
        }
        
    };

    $.fn.ledSimulator = function( method ) {
    
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.ledSimulator' );
        }
    
    };

})( jQuery );
