function sign(number){
    return number>=0?1:-1;
}

var CMONTH = new Class({
    Extends: Converter,
    fromCode: function(value){
        return parseInt(value);
    },
    fromHash: function(value){
	value = parseInt(value)-1;
	if(isNaN(value))
	    return this.defaultValue;
	return value;
    },
    toHash: function(value){
	if(value==this.defaultValue)
	    return false;
	return value+1;
    }    
});

var Button = new Class({
    aElements: Array(),
    initialize: function(timeline, left, width, date, active)
    {
	this.timeline = timeline;
	this.date = date;
	this.active = active;
	this.createElement();
	this.setLeft(left);
	this.setWidth(width);
	this.makeDragable();
	this.aElements = this.element.getElements('a'); //XXX
    },
    setLeft: function(left){
        this.left = left;
	this.element.setStyle('left', left);
    },
    setWidth: function(width){
        this.width = width;
	this.element.setStyle('width',width);
    },
    makeDragable: function(){
        this.dragInstance =  new Drag(this.element,{
	     grid:5,
	     modifiers:{'x':'left','y':''},
    	     onDrag: this.onDrag.bind(this),
	     onStart: this.onDragStart.bind(this),
	     onComplete: this.onDragComplete.bind(this)
	});
	//Fix for IE
	this.dragInstance.handles.ondragstart = function(){ return false; };
    },
    onDrag: function(el){
        if(this.timeline.blocked)
	    return;
        $clear(this.timeline.periodId);
        this.drag(el);
    },
    drag: function(el){
        if(this.timeline.blocked)
	    return;
        var elLeft = parseInt(this.element.getStyle('left'));
        var delta = elLeft - this.left;
	if(Math.abs(delta)<this.timeline.delta) return;
	var selected = this.timeline.selected;
	if((selected.date>=this.timeline.lastDate)&&(delta<0)&&
	             (this.timeline.pointer>selected.left+selected.width/2)){
	    this.setLeft(this.left);
	    return;
	}
	if((selected.date<=this.timeline.firstDate)&&(delta>0)&&
	             (this.timeline.pointer<selected.left+selected.width/2)){
	    this.setLeft(this.left);
	    return;
	}
	this.setLeft(elLeft);
	this.timeline.buttons.each(function(item){
	    if(item.element!=this.element)
	        item.setLeft(parseInt(item.element.getStyle('left'))+delta);
	}.bind(this));
	var selected  = this.timeline.selected;
	if((selected.left > this.timeline.pointer) || 
	                (selected.left+selected.width < this.timeline.pointer))
	    this.timeline.setSelectedButton();
	var firstButton = this.timeline.buttons[0];
	var lastButton = this.timeline.buttons.getLast();
	if(firstButton.left>0){
	    var newDate =  firstButton.date.addDays(-1);
	    var dateInfo = this.timeline.dates.get(newDate.key());
	    if(dateInfo==null){
		this.timeline.loadMonth(newDate);
	        return;
	    }
	    this.timeline.buttons.splice(0,0, new Button(this.timeline, 
	                       firstButton.left-firstButton.width,
			       firstButton.width,
			       newDate, Boolean(dateInfo)
	    ));
            if(lastButton.left > this.timeline.width){
                this.timeline.buttons.pop().remove();
            }
	}
	if((lastButton.left+lastButton.width)<this.timeline.width){
	    var newDate =  lastButton.date.addDays(1);
	    var dateInfo = this.timeline.dates.get(newDate.key());
	    if(dateInfo==null){
		this.timeline.loadMonth(newDate);
	        return;
	    }
	    this.timeline.buttons.extend([new Button(this.timeline, 
	                       lastButton.left+lastButton.width,
			       lastButton.width,
			       newDate, Boolean(dateInfo)
	    )]);
	    if((firstButton.left + firstButton.width) < 0){
                this.timeline.buttons.shift().remove();
	    }
	}
    },
    onDragStart: function(el){
        this.aElements.addEvent('click', function(event){event.stop()});
    },
    onDragComplete: function(el){
//	this.aElements.removeEvents.delay(1000,this.aElements,["click"]);
	if(this.timeline.isBlocked) return
	if(this.timeline.isSelectedChanged){
	    this.timeline.isSelectedChanged = false;
	    this.timeline.showMainEvent.delay(1000,this.timeline);
	}
    },
    createElement: function(){    
        var data = this.getDateInfo()
        var newbutton = new Element('div', {'class':'button',
                           'style':'xz-index:1;position:absolute;'});
	if(this.date.getTime()==this.timeline.todayDate.getTime())
	    newbutton.addClass('bgblue');
        if(data){
	    var a = new Element('a',{'href': this.path()}).inject(newbutton);
	    Element('img',{'src': '/img/img2/b02/0.gif',
	               'width':'100%',
		       'height':'54px'}).inject(a);

	    
	    var newday = new Element('div',{'class':'day',
	                                'style':'width:100%'
            }).inject(newbutton);
	    Element('a', {'href': this.path(), 
	              'html': this.formatDate(this.date)}).inject(newday);

            this.bubble = Element('div', {'class': 'bubbleZ'}).inject(newday); 
	
	    this.preview = new Element('div',
                              {'class':'preview-img right'}).inject(newbutton);
            var preview = this.preview;
	    var a = Element('a',{'href': this.path(),
	                     'class':'thumb'}).inject(preview);
            a.addEvent('click', function(e){
		         e.stop();
	 	         this.timeline.moveToDate(false, this.date);
	    }.bind(this));

            Element('img', {'src': data.preview}).inject(a);
            var div = Element('div',{'class':'redcircle'}).inject(preview)
            Element('div',{'class':'rc-bg',
                           'html': data.counter}).inject(div);
                           
            var div = Element('div',{'class':'overRight'}).inject(preview);
            var div2 = Element('div',{'class':'preview-text'}).inject(div);
            Element('a', {'href': this.path(),
                          'html': data.title}).inject(div2);
                          
            var div3 = Element('div',{'class':'preview-allnews'}).inject(div);
            Element('a', {'href': this.path(),
                          'html': 'all events'}).inject(div3);
        }else{
	    Element('img',{'src': '/img/img2/b02/0.gif',
	               'width':'100%',
		       'height':'54px'}).inject(newbutton);	    
	    var newday = new Element('div',{'class':'day',
                                     'html': this.formatDate(this.date),
	                             'style':'xborder-style:solid;width:100%'
            }).inject(newbutton);

        }      
        this.element = newbutton;
        newbutton.inject(this.timeline.element);
    },
    formatDate: function(date){
        var result = date.getDate() + " " + MONTHNAMES[date.getMonth()];
        var year = date.getFullYear();
	if(year!=this.timeline.curDate.getFullYear())
	    result+=" "+year;
	return result;
    },
    path: function(){
        return prefix+'/'+this.date.getFullYear()+ '/'+(this.date.getMonth()+1)+'/'+this.date.getDate() + '/';
    },
    remove: function(){
        this.element.destroy();
    },
    getDateInfo: function(){
        return this.timeline.dates.get(this.date.key());
    }
});

var Timeline = new Class({
    buttonsWidthMul: 0.13,
    buttonsMarginLeft: 36,
    delta: 10,
    buttons: [],
    dates: $H(),
    blocked: false,
    pointer: 0,
    requestCounter:0,
    initialize: function(el, curDate, firstDate, lastDate, todayDate, main_bubble){
        this.todayDate = todayDate;
        this.element = el;
	this.firstDate = firstDate;
	this.lastDate = lastDate;
	this.curDate = curDate;
        this.pointer_div = $$('.b04-bubbleMore')[0];


        // set main_bubble
	this.main_lead = main_bubble.getElement('.quote').getElement('a');
	this.main_lead_person = main_bubble.getElement('.who');
	this.main_lead_place = main_bubble.getElement('.where');
	this.main_img = main_bubble.getElement('.ill').getElement('img');
	this.main_title = main_bubble.getElement('.ill').getElement('a');
        this.main_title_p = main_bubble.getElement('.ill').getElement('p');
	this.main_links = main_bubble.getElement('.linkLine');

	this.width = el.getWidth();
	this.buttonsMarginLeft = this.width * 0.04;


	this.setPointer();
	this.leftArrow = el.getElement('.tlLeftArrow');
	this.leftArrow.setStyle('z-index',2000);
	document.getElement('.wspace_left').setStyles(
                        {'z-index':"1999",'position':'absolute', 'left':'0px'});
	this.leftArrow.addEvent('click',this.moveLeft.bind(this));
	this.rightArrow = el.getElement('.tlRightArrow');
	this.rightArrow.setStyle('z-index',2000);
	document.getElement('.wspace_right').setStyles(
                       {'z-index':"1999",'position':'absolute', 'right':'0px'});
	
	this.rightArrow.addEvent('click',this.moveRight.bind(this));
	window.addEvent('resize', function(e){
	    this.width = this.element.getWidth();
	    this.buttonsMarginLeft = parseInt(this.width * 0.04);
	    buttonWidth = this.getButtonWidth();
	    this.setPointer();
	    this.buttons.each(function(item, ind){
	    	item.setLeft(this.buttonsMarginLeft + ind * (buttonWidth));
		item.setWidth(buttonWidth);
	    }.bind(this));
        }.bind(this));	
	hashController.addParam("year", new CINT(curDate.getFullYear()));
	hashController.addParam("month", new CMONTH(curDate.getMonth()));
	hashController.addParam("day", new CINT(curDate.getDate()));
        hashController.addHandler(this.changeHash.bind(this));

    },
    setPointer: function(){
    //a=b
        var x = 0;//this.pointer_div.getPosition().x;
	var shift = parseInt(this.pointer_div.getWidth() * 0.65)+27;
        this.pointer=x+shift;//this.day_pointer.getPosition().x;
    },
    run: function(){
        hashController.run(1); 
	this.jumpTo(this.curDate);
    },
    jumpTo: function(date){
        // buttons init
	date = date<this.firstDate?this.firstDate:date;
	date = date>this.lastDate?this.lastDate:date;
	this.curDate = date
	this.block();
	$clear(this.periodId);
	var startDate = this.curDate.addDays(-3); 

        var loadStartDate = !this.dates.has(startDate.key());
	if(loadStartDate){
	    this.loadMonth(startDate, this.jumpTo, [date]);
	    return;
	}
	var endDate = this.curDate.addDays(4);
        var loadEndDate = !this.dates.has(endDate.key());
	if(loadEndDate){
	    this.loadMonth(endDate, this.jumpTo, [date]);
	    return;
	}
	var buttonWidth = this.getButtonWidth();
	this.element.getElements('.button').destroy();
	this.buttons=[];
	for(var x=-3; x<4; x++){
	    date = this.curDate.addDays(x);
	    var button = new Button(this, 
	                       this.buttonsMarginLeft + (x+3) * buttonWidth,
			       buttonWidth,
			       date, Boolean(this.dates[date.key()])
	    );
            this.buttons.push(button);
	    if(!x) this.selected = button;
	}
	this.setSelectedButton(1);
	this.showEvents(1);
	this.unblock();
    },
    getButtonWidth: function(){
        return parseInt(this.width * this.buttonsWidthMul);
    },
    initMonth: function(date, days){
        if(this.dates.has(date.key()))
	    return;
	days.each(function(item, index){
	    this.dates[date.addDays(index).key()] = item;
        }.bind(this));
    },
    loadMonth: function(date, handler, args){
        var jsonRequest = new Request.JSON({
	    url: prefix+"/"+date.getFullYear()+"/"+(date.getMonth()+1)+'/ajax/',
	    link: 'chain',
	    onRequest: function(){
	        this.block();
                this.requestCounter++;
	    }.bind(this),
	    onSuccess: function(response){
	//      alert('success');
	        this.initMonth(
		    new Date(response.year, response.month-1, 1),response.days);
	//alert('end:'+response.month);
		this.unblock();
		this.requestCounter--;
		if(handler&&(!this.requestCounter))
		    handler.run(args, this);
	    }.bind(this),
	    onFailure: function(request){
	        if(request.status==403){
//		    this.loadMonth.delay(1000,this,[date, handler, args]);
		}else{
		    this.unblock();
		    alert('server error:'+request.status);
		}
	     }.bind(this)
	}).get();
    },
    block: function(){
//        $clear(this.periodId);
        this.blocked = true;
        this.buttons.each(function(item){item.dragInstance.options.style=false})
    },
    unblock: function(){
        this.blocked = false;
        this.buttons.each(function(item){item.dragInstance.options.style=true}) 
    },
    setSelectedButton: function(fast){
        this.buttons.each(function(item){	
            if((item.left<=this.pointer)&&(item.left+item.width>this.pointer)){
                if(this.selected)
		    this.selected.element.removeClass('bggray');
                    if(this.selected.preview){
                        if(fast){
                          this.selected.preview.setStyle('visibility','');
                          this.selected.bubble.setStyle('visibility',''); 
                        }else{
                            this.selected.preview.fade('in');
                            this.selected.bubble.fade('in');
                        }
                }
                this.selected = item;
		this.selected.element.addClass('bggray');
                if(this.selected.preview){
                        if(fast){
                          this.selected.preview.setStyle('visibility','hidden');
                          this.selected.bubble.setStyle('visibility','hidden'); 
                        }else{
                          this.selected.preview.fade('out');
                          this.selected.bubble.fade('out');
                        }
                }
		this.isSelectedChanged = true;
		hashController.setParams($H({'year':item.date.getFullYear(),
		                             'month':item.date.getMonth(),
					     'day':item.date.getDate()}))
	    }
	}.bind(this));
	this.showArrows();
    },
    showEvents: function(fast){
       dateInfo = this.dates.get(this.selected.date.key());
       this.showArrows();
       if(!dateInfo){
           this.moveLeft();   
	   return;
       }
       this.showMainEvent(fast);
    },
    showMainEvent: function(fast){
        var info = this.selected.getDateInfo();
        if(!info) return;
        if(this.main_event_info==info){
            return;
        }else{
           this.main_event_info = info;
        }
        if(this.main_event_timer) 
            $clear(this.main_event_timer);
        var changed_elements  = $$(this.main_lead, 
                        this.main_lead_person, 
                        this.main_lead_place,
                        this.main_img, this.main_title, 
                        this.main_title_p, this.main_links);
        if(!fast)
            changed_elements.fade('out');
        function show(){
	this.main_lead.set('html',info.lead);
        this.main_lead.set('href', info.url);
	this.main_lead_person.set('html', info.lead_person);
	this.main_lead_place.set('html', info.lead_place);
	this.main_img.set('src', info.img);
	this.main_title.set("html", info.title);
        this.main_title.set("href", info.url);
	this.main_links.set("html", "");
	for(var x=0; x<info.links.length;x++){
	    if(x){
	        this.main_links.innerHTML+=" / ";
	    }
	    Element('a',{'html':info.links[x][0],
	            'href':info.links[x][1]}).inject(this.main_links);
	}
        changed_elements.fade('in');
        }
        this.main_event_timer = show.delay(fast?0:500, this);
    },
    initEvents: function(date, events){
        if(this.dates[date.key()][1]!=1)
	    return;
	this.dates[date.key()][1] = events;
    },
    loadEvents: function(date){    
        var jsonRequest = new Request.JSON({
	    url: prefix+"/"+date.getFullYear()+"/"+(date.getMonth()+1)+'/'+date.getDate()+'/ajax/',
	    link: 'ignore',
	    onRequest: function(){
	        this.block();
	    }.bind(this),
	    onSuccess: function(response){
	        this.initEvents(date, response.events);
		if(this.selected.date==date)
		    this.createEvents(response.events)
		this.unblock();
	    }.bind(this),
	    onFailure: function(request){
	        if(request.status==403){
//		    this.loadEvents.delay(1000,this,[date]);
		}else{
		    this.unblock();
		    alert('server error:'+request.status);
		}
	     }.bind(this)
	}).get()
    },
    changeHash: function(changed, params){
        if(self.blocked)
	    return;
        $clear(this.timeoutId);
        this.jumpTo(new Date(params.year, params.month, params.day));
    },
    showArrows: function(){
        if(this.selected.date<=this.firstDate)
	    this.leftArrow.setStyle('display','none');
	else
	    this.leftArrow.setStyle('display','block');
        if(this.selected.date>=this.lastDate)
            this.rightArrow.setStyle('display','none');
        else
            this.rightArrow.setStyle('display','block');	
    },
    moveToDate: function(e,date){
        if(this.selected.date == date)
	    return;
        if(this.selected.date > date)
	    this.moveLeft(e, date);
	if(this.selected.date < date)
	    this.moveRight(e, date);
    },
    moveLeft: function(event, date){
        if(event) event.stop();
	$clear(this.periodId);
	if(this.selected.date<=this.firstDate) return;
	this.moveStartDate = this.selected.date;
        this.periodId = this.moveSelectedButton.periodical(80, this, [this.delta, date])
    },
    moveRight: function(event, date){
        if(event) event.stop();
	$clear(this.periodId);
	if(this.selected.date>=this.lastDate) return;
	this.moveStartDate = this.selected.date;
        this.periodId = this.moveSelectedButton.periodical(80, this, [-this.delta, date])
    },
    moveSelectedButton: function(delta, date){
        if(this.isBlocked) return;
        this.selected.element.setStyle('left', this.selected.left+delta);
	this.selected.drag(this.selected);
	if((this.selected.date!=this.moveStartDate)&&(!(date&&(this.selected.date!=date)))){
	    var info = this.selected.getDateInfo()
	    if(info&&(sign(delta) * (this.pointer-/*this.buttonsMarginLeft*/+1)<=
                     sign(delta) * (this.selected.left+this.selected.width/2))){
	        $clear(this.periodId);
	        this.selected.onDragComplete(this.selected);
	    }
	}
    }
});


