
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)<10) 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.showEvents.delay(1000,this.timeline);
	}
    },
    createElement: function(){
        var newbutton = new Element('div', {'class':'button',
	                            /*'style':'xborder-style:solid;position:absolute;z-index:500'});*/
	                            'style':'xborder-style:solid;position:absolute;'});
	if(this.date.getTime()==this.timeline.todayDate.getTime())
	    newbutton.addClass('bgblue');
	var newday = new Element('div',{'class':'day'});
	var img = new Element('img',{
	              'src':"/img/0.gif",
		      'width':"123",
		      'height':"38",
		      'border':"0"});
	var text = this.formatDate(this.date).toUpperCase();
        if(this.active){
	     this.aElements[0] = new Element('a', {href:this.path()});
	     this.aElements[0].inject(newbutton);
	     img.inject(this.aElements[0]);
	     this.aElements[1] = new Element(
	                                 'a',{href:this.path(), 'text':text});
	     this.aElements[1].inject(newday);
	     this.aElements.each(function(item){
	         item.addEvent('mouseover', function(e){
		     if(this!=this.timeline.selected)
		         this.element.addClass('bggray');
		 }.bind(this));
	         item.addEvent('mouseout', function(e){
		     if(this!=this.timeline.selected)
		         this.element.removeClass('bggray');
		 }.bind(this));
	         item.addEvent('click', function(e){
		 try{
		     e.stop();
	 	     this.timeline.moveToDate(false, this.date);
		 }catch(err){alert(err)};
		 }.bind(this));
	     }.bind(this));
	}else{
	     newday.set('text',text);
	     img.inject(newbutton);
	}
	this.element = newbutton;
	newday.inject(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.14,
    buttonsMarginLeft: 26,
    buttons: [],
    dates: $H(),
    blocked: false,
    pointer: 0,
    requestCounter:0,
    initialize: function(el, curDate, firstDate, lastDate, todayDate, bubbleCloser){
        this.todayDate = todayDate;
        this.element = el;
	this.firstDate = firstDate;
	this.lastDate = lastDate;
	this.bubbleCloser=bubbleCloser;
	this.listdiv = $(el.id+"-listdiv");
	this.width = el.getWidth();
	this.wrap = document.getElement('.wrap');
	this.day_pointer = document.getElement('.b12-P01-day_pointer')
	this.curDate = curDate;
	this.setPointer();
	this.leftArrow = el.getElement('.tlLeftArrow');
	this.leftArrow.setStyle('z-index',1000);
//	document.getElement('.wspace_left').setStyle('z-index',999);
	this.leftArrow.addEvent('click',this.moveLeft.bind(this));
	this.rightArrow = el.getElement('.tlRightArrow');
	this.rightArrow.setStyle('z-index',1000);
//	document.getElement('.wspace_right').setStyle('z-index',999);
	this.rightArrow.addEvent('click',this.moveRight.bind(this));
	window.addEvent('resize', function(e){
	    this.width = this.element.getWidth();
	    buttonWidth = this.getButtonWidth();
	    this.setPointer();
	    this.buttons.each(function(item, ind){
	    	item.setLeft(item.left - ind * (item.width-buttonWidth));
		item.setWidth(buttonWidth);
	    });
        }.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(){
        this.pointer=this.day_pointer.getPosition().x-this.wrap.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.element.getElements('.button_bgblue').destroy();
	this.buttons=[];
	for(var x=-3; x<4; x++){
	    date = this.curDate.addDays(x);
	    //alert(date);
	    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();
	this.showEvents();
	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){
	        item = (!item[0]&&!item[1])? false: item;
		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(){
        this.buttons.each(function(item){
            if((item.left<=this.pointer)&&(item.left+item.width>this.pointer)){
                if(this.selected)
		    this.selected.element.removeClass('bggray');
                this.selected = item;
		this.selected.element.addClass('bggray');
		this.isSelectedChanged = true;
		hashController.setParams($H({'year':item.date.getFullYear(),
		                             'month':item.date.getMonth(),
					     'day':item.date.getDate()}))
	    }
	}.bind(this));
	this.showArrows();
    },
    showEvents: function(){
       dateInfo = this.dates.get(this.selected.date.key());
       this.showArrows();
       if(!dateInfo||!dateInfo[1]){
           this.moveLeft();   
	   return;
       }
       if(dateInfo[1]==1){
           this.loadEvents(this.selected.date);
	   return;
       }
       this.createEvents(dateInfo[1], dateInfo[2]);
    },
    createEvents: function(events, open_message){
       this.listdiv.setStyle('display','none');
       this.listdiv.empty();
       var events_cnt = events.length;
       events.each(function(item, index){
       	   if(item.annonce)
               var container = new Element('div',{'class':'open'});
	   else
               var container = new Element('div',{'class':'close'});

           var linediv = new Element('div',{'class':'middle-'+item.type_cls});
	   linediv.inject(container)

	   if(item.annonce){
	       var toggle=Element('a',{'class':'news-toggle', 'href':'#'}).inject(linediv);
	       toggle.addEvent('click', function(e){ 
	           e.stop()
	           container.className = container.className=='open'?'close':'open';
	       });
	   }
	   var left = new Element('div', {'class':'left'});
	   var left_a = Element('a',{'href':item.href}).inject(left);
	   Element('img',{"src":item.photo}).inject(left_a);
	   left.inject(linediv);
	   var right = new Element('div', {'class':'right'});
	   var right_title = new Element('div').inject(right);
	   Element('a',{'href':item.href,'html':item.title}).inject(right_title);
	   Element('div',{'class':'extra-content','html':item.annonce}).inject(right);
	   right.inject(linediv)
	   container.inject(this.listdiv,'bottom');
	   if(index==events_cnt-1){
               var hrImg = Element('img', {width:'484px', height:'2px', src:'/img/img4/b11-P01/hrTop.jpg'});
               var hr = Element('div',{'class':'hrTop'});
	   }else{
               var hrImg = Element('img', {width:'484px', height:'2px', src:'/img/img4/b11-P01/hr.jpg'});
               var hr = Element('div',{'class':'hr'});
	   }
           hrImg.inject(hr);
           hr.inject(this.listdiv, 'bottom');

       }.bind(this));
       
       this.bubbleCloser.init(open_message);
       this.listdiv.setStyle('display','block'); 
    },
    initEvents: function(date, events, open_message){
        if(this.dates[date.key()][1]!=1)
	    return;
	this.dates[date.key()][1] = events;
        this.dates[date.key()][2] = open_message;
    },
    loadEvents: function(date){    
        var jsonRequest = new Request.JSON({
	    url: prefix+"/"+date.getFullYear()+"/"+(date.getMonth()+1)+'/'+date.getDate()+'/ajax/',
	    link: 'ignore',
	    onRequest: function(){
	        this.block();
	  //alert('request '+ date);
	    }.bind(this),
	    onSuccess: function(response){
	        this.initEvents(date, response.events, response.open_message);
		if(this.selected.date==date)
		    this.createEvents(response.events, response.open_message);
	//	alert('end:');
		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, [10, 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, [-10, 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&&info[1]&&(sign(delta) * (this.pointer-/*this.buttonsMarginLeft*/+1)<=
                     sign(delta) * (this.selected.left+this.selected.width/2))){
	        $clear(this.periodId);
	        this.selected.onDragComplete(this.selected);
	    }
	}
    }
});

var temp;
var timeline;
