// helper class for effects
var SwEffectChain = new Class({
    Implements: Chain,
    initialize: function(){
		this.backgroundColor = new Array();
        this.runChain = function(){
            this.callChain();
            if (this.$chain.length == 0) {
                this.stop();
            }
        }.bind(this);
    },
	rocketEffect: function(y, bgColor) {
        var currentDiv = $('x' + this.x + ' y' + y);
        highlight = new Fx.Tween(currentDiv, {
            property: 'background-color',
            duration: 1200
        });
        highlight.start('#fff', bgColor);
	},
	openWindow: function(item) {
		content = $(item.get('id')+'-content');
		var expendContent = new Fx.Morph(content, {duration:100});
		expendContent.start('.content-final');
	},
	closeWindow: function() {
		openedWindows = $$('section');
		openedWindows.each(function(windowItem){
			if (parseInt(windowItem.getStyle('width')) > 0) {
				windowItem.getFirst().setStyle('display', 'none');
				var collapseContent = new Fx.Morph(windowItem, {duration:100});
				collapseContent.start('.init-' + windowItem.get('id'));
			}
		});
	},
	displayContent: function(item) {
		$(item.get('id')+'-content').getFirst().setStyle('display', 'block');
	},
	stop: function() {
		$clear(this.timer);
		this.timer=0;
	},
    start: function(item, img){
        this.x = parseInt(item.getStyle('left')) / parseInt($('x0 y0').getStyle('width')) + 2;
        this.chain(
			function(){ this.rocketEffect(15, '#'+img.data[15][this.x]); },
			function(){ this.rocketEffect(14, '#'+img.data[14][this.x]); },
			function(){ this.openWindow(item); },
			function(){ this.displayContent(item); }
		);
        if (!this.timer) this.timer = this.runChain.periodical(100);
    },
	collapse: function() {
		this.clearChain();
		if (this.timer) {
			this.chain(function(){
				this.closeWindow();
			});
		} else {
				this.closeWindow();
		}
	}
});

// speed: nb of ms between 2 nextAction calls
// mode= 1:line by line, pixel by pixel
// mode= 2:line by line
// mode= 3: mouseover
// nbOfPictures: nbOfPictures to be shown in the slideshow
var SwPixelBoard = new Class({
    Implements: Options,
    options: {
        speed: 500,
        nbOfPictures: 5,
        mode: 3,
        image: 'bg1.png',
		currentDirectory: window.location.href + 'images/'
    },
    initialize: function(el, options){
        this.setOptions(options);
        this.el = $(el);
        this.x = 0;
        this.y = 0;
        this.image = 0;
        this.timer = 0;
        this.pictureIndex = 1;
		this.selectedItem = 0;
		this.effectChain = new SwEffectChain();
        var jsonRequest = new Request.JSON({
            url: "lib/php/getimageobject.php",
            onSuccess: function(img){
                this.image = img;
                if (!img) 
                    alert('image not found! ' + this.options.currentDirectory + this.options.image);
                this.displayFirst();
            }
.bind(this)
        }).get({
            'filepath': this.options.currentDirectory + this.options.image
        });
        $$('.menu-item').each(function(item){
            item.addEvents({
            	'mouseenter': function(item){
						if (this.selectedItem && item!==this.selectedItem) this.deselect(item);
	                    if (!this.selectedItem) {
							item.addClass('selected');
							this.selectedItem = item;
							this.effectChain.start(item, this.image);
						}
                	}.bind(this, item),
                'click': function(item){
						if (this.selectedItem) this.deselect(item);
						else {
							item.addClass('selected');
							this.selectedItem = item;
							this.effectChain.start(item, this.image);
						}
                	}.bind(this, item),
            });
        }, this);
		$('background').addEvent('click', function(){this.deselect()}.bind(this));
    },
	
	deselect: function() {
		if (this.selectedItem) {
			this.selectedItem.removeClass('selected');
			this.effectChain.collapse();
			this.selectedItem=0;
		}
	},
    
    initImage: function(){
        var jsonRequest = new Request.JSON({
            url: "lib/php/getimageobject.php",
            onSuccess: function(img){
                if (!img) 
                    alert('image not found!');
                this.image = img;
                this.pixels = this.el.getChildren();
                this.nextAction();
            }
.bind(this)
        }).get({
            'filepath': this.options.currentDirectory + 'bg' + this.pictureIndex + '.png'
        });
    },
    
    displayFirst: function(){
        for (y = 0; y < this.image.height; y++) {
            for (x = 0; x < this.image.width; x++) {
                var wrap = new Element('div', {
                    'id': 'x' + x + ' y' + y,
                    'styles': {
                        'background-color': "#" + this.image.data[y][x]
                    }
                });
                //				wrap.addClass('x'+x);
                //				wrap.addClass('y'+y);
                this.el.grab(wrap);
                if (!this.pixelSizeX) {
                    this.pixelSizeX = parseInt(wrap.getStyle('width'));
                    this.pixelSizeY = parseInt(wrap.getStyle('height'));
                }
                wrap.setStyles({
                    left: this.pixelSizeX * x,
                    top: this.pixelSizeY * y
                });
                if (this.options.mode == 3) {
                    wrap.addEvents({
                        mouseenter: function(){
                            this.setStyle("background-color", "white");
                        },
                        mouseleave: function(img){
                            x = parseInt(this.getStyle('left')) / parseInt(this.getStyle('width'));
                            y = parseInt(this.getStyle('top')) / parseInt(this.getStyle('height'));
                            backgroundColor = "#" + img.data[y][x];
                            this.set('tween', {
                                duration: 'long'
                            });
							var color = "#ff" + Math.round(x*8.5).toString(16) + Math.round(y*12.8).toString(16)
                            this.tween('background-color', color, backgroundColor);
                        }
.bind(wrap, this.image)
                    });
                    if (x == 0 && y == 0) {
                        wrap.addClass('topleft');
                    }
                    if (x == 0 && y == this.image.height - 1) {
                        wrap.addClass('bottomleft');
                    }
                }
            }
        }
        if (this.options.mode !== 3) {
            this.nextPicture();
        }
    },
    
    nextPicture: function(){
        this.pictureIndex++;
        if (this.pictureIndex > this.options.nbOfPictures) {
            this.pictureIndex = 1;
        }
        this.initImage();
    },
    
    nextAction: function(){
        switch (this.options.mode) {
            case 1:
                this.executeModePixelByPixel.periodical(this.options.speed, this);
                break;
            case 2:
                this.executeModeLineByLine.periodical(this.options.speed, this);
                break;
            case 3:
                break;
        }
    },
    
    executeModePixelByPixel: function(){
        var currentElement = this.pixels[0];
        if (!currentElement) 
            return;
        var backgroundColor = "#" + this.image.data[this.y][this.x];
        currentElement.setStyle('background-color', backgroundColor);
        this.pixels.erase(currentElement);
        this.x += 1;
        if (this.x == this.image.width) {
            this.x = 0;
            this.y += 1;
        }
        if (!this.pixels.length || this.y == this.image.height) {
            this.x = 0;
            this.y = 0;
            $clear(this.timer);
            this.nextPicture();
        }
    },
    
    executeModeLineByLine: function(){
        this.x = 0;
        while (this.x != this.image.width) {
            var currentElement = this.pixels[0];
            if (!currentElement) 
                return;
            var backgroundColor = "#" + this.image.data[this.y][this.x];
            currentElement.setStyle('background-color', backgroundColor);
            this.pixels.erase(currentElement);
            this.x += 1;
        }
        this.x = 0;
        this.y += 1;
        if (!this.pixels.length || this.y == this.image.height) {
            this.y = 0;
            $clear(this.timer);
            this.nextPicture();
        }
    }
});

