Notifier = {
    '_notifications': [],
    '_bubbles': [],
    '_intervalID': false,
    '_vertical_offset': 5,
    'createBubble': function(props) {
        bubble = document.createElement('div');
        
        bubble = tag('div', {});
	      bubble.className = 'floating_notification type-' + props.type;
                
        if (props.title) {                       
            bubble_title = tag('div', {'class': 'floating_notification_title'});
            bubble_title.appendChild(txt(props.title));            
            bubble.appendChild(bubble_title);
        }
        
        bubble_message = tag('div', {'class': 'floating_notification_message'});
        
        if (typeof(props.message) == 'object') {
            bubble_message.appendChild(props.message);            
        } else {
            bubble_message.innerHTML = props.message;                
        }
        
        bubble.appendChild(bubble_message);
        this._bubbles.push(bubble);
        return bubble;
    },
    'notify': function(message, user_options) {
        options = {onClick: false, onExpire: false, life_time: 7000, title: '', type: 'info'};

        
        for(var k in user_options) {
            options[k] = user_options[k];
        }
        
        bubble = this.createBubble({message: message, title: options.title, type: options.type});
        Event.observe(bubble, 'click', this._onBubbleClicked.bind(this));
        
        document.getElementById('content').appendChild(bubble);
        
        make_transparent(bubble, 0.9);
        
        notification = {}    
        notification.bubble = bubble;
        notification.timestamp = new Date();
        notification.message = message;
        notification.options = options;

        bubble.destroy = function() {
            this.parentNode.removeChild(this);
        }
        
        bubble.getNotificationIndex = function() {
            return parseInt(this.id.substring('floating_notification_'.length));
        }
        bubble.id = 'floating_notification_' + this._notifications.length;
        
        if (this._bubbles.length > 1) {
            prev = this._bubbles[this._bubbles.length - 2];
            t = prev.offsetTop + Element.getHeight(prev) + this._vertical_offset;
            bubble.style.top = t + 'px';
        }
        
        this._notifications.push(notification);
        if (this._intervalID == false) {    
            this._intervalID = setInterval(this._monitor.bind(this), 500);
        }
        
    },
    '_removeBubble': function(bubble) {
        bubble_index = bubble.getNotificationIndex();
        bubble_height = Element.getHeight(bubble);
        
        bubble.destroy(this);
        //this._moveUpBubbles(bubble_index, bubble_height);
        
        old_bubbles = this._bubbles;
        this._bubbles = [];
        for(var  i = 0; i < old_bubbles.length; i++) {
            if (old_bubbles[i].getNotificationIndex() != bubble_index) {
                this._bubbles.push(old_bubbles[i]);
            } 
        }        
    },
    '_moveUpBubbles': function(ref_index, ref_height) {
        for(var i = ref_index + 1; i < this._bubbles.length; i++) {
            other_bubble = this._bubbles[i];
            other_bubble.style.top = (other_bubble.offsetTop - this._vertical_offset - ref_height) + 'px';            
        }
    },
    '_onBubbleClicked': function(e) {
        el = Event.element(e);
        
        if (Element.hasClassName(el, 'floating_notification')) {
            bubble = el;
        } else {
	    bubble = find_parent_node(el, 'div', 'floating_notification');
        }
        
        if (el.nodeName.toLowerCase() != 'a') {
            if (notification.options.onClick != undefined && notification.options.onClick != false) {
                if (typeof(notification.options.onClick) != 'function') {
                    location.href = notification.options.onClick;
                } else {
                    notification.options.onClick();
                }
            }
        }
        
	if (bubble == false || bubble == undefined) {
	   return;
	}
        this._removeBubble(bubble);

    },
    '_monitor': function() {
        bubbles = this._bubbles;
        now = new Date();
        for(var i = 0; i < bubbles.length; i++) {
            bubble = bubbles[i];
            notification = this._notifications[bubble.getNotificationIndex()];
            diff = now.getTime() - notification.timestamp.getTime();
            if (notification.options.life_time > 0 && diff > notification.options.life_time) {
                this._removeBubble(bubble);
                if (notification.options.onExpire) {
                    notification.options.onExpire(notification);
                }                
            }
        }
        
        if (this._bubbles.length == 0) {
            clearInterval(this._intervalID);
            this._intervalID = false;
        }        
    }
}

function notify(message, options) {
    Notifier.notify(message, options);
}
