﻿var DayEventsRenderer = function(){this.ctor.apply(this, arguments);};Object.SetProperties(DayEventsRenderer.prototype, 
{
   ctor:function()
   {
     var args = Object.ToArray(arguments);
     this.EManager = args[0];
   },
   EManager:null,
   ShowingDate:new Date(),

   HourDistance: function(d1, d2, unit)
   {
        
     var m1 = new Date(d1<d2?d1:d2);
     var m2 = new Date(d1<d2?d2:d1);
     
     m1.setHours(m1.getHours(),0,0,0);
     m2.setHours(m2.getHours(),0,0,0); 
     
     return (m2-m1)/(unit*3600000);
   },
      
   CoverHour: function(d1, d2, unit)
   {
        
     var m1 = new Date(d1<d2?d1:d2);
     var m2 = new Date(d1<d2?d2:d1);
     
     m1.setHours(m1.getHours(),0,0,0);
     m2.setHours(m2.getHours()+((m2.getMinutes()>0)?1:0),0,0,0); 
     
     return (m2-m1)/(unit*3600000);
   },
      
   Render:function(body, list)
   {

      body.innerHTML = "";
      this.ShowingDate = this.EManager.ShowingDate;

      var styles = this.EManager.Styles.Day;
      var labels = this.EManager.Labels.Day;
      var settings = this.EManager.Settings.Day;
         

      // Date calculation
      
      var date = this.EManager.ShowingDate;
      var sDate = new Date(date); sDate.setHours(0,0,0,0);
      var eDate = new Date(sDate); eDate.setDate(eDate.getDate()+1); eDate.setMilliseconds(-1);
      var yearRange = new Range(sDate, eDate, true, true);
      
      var cDate = new Date(sDate);
            
      // Render Day Select Container
      var div0 = Object.NewTagInto(body, "div", {style:{textAlign:'right', height:'8%', width:'100%'}});


      // Render Day Select
      var dSel = Object.NewTagInto(div0, "select", styles.GetStyle("Select"));
      for(var i=1; i<=31; i++){
        Object.NewTagInto(dSel, "option", {innerHTML:i, value:i, selected:this.ShowingDate.getDate()==i});
      }
      
      // Render Month Select
      var mSel = Object.NewTagInto(div0, "select", styles.GetStyle("Select"));
      for(var i=0; i<12; i++){
        Object.NewTagInto(mSel, "option", {innerHTML:Date.MonthLabels[i].substr(0,3).toUpperCase(), value:i+1, selected:this.ShowingDate.getMonth()==i});
      }
      
      // Render Year Select
      var ySel = Object.NewTagInto(div0, "select", styles.GetStyle("Select"));
      var cMonth = new Date(this.ShowingDate); cMonth.setFullYear(cMonth.getFullYear()-10);
      for(var i=0; i<20; i++){
        Object.NewTagInto(ySel, "option", {innerHTML:cMonth.getFullYear(), value:cMonth.getFullYear(), selected:this.ShowingDate.getFullYear()==cMonth.getFullYear()});          
        cMonth.setFullYear(cMonth.getFullYear()+1);
      }
      
      var btnGo = Object.NewTagInto(div0, "input", {type:'button', value:'Go'});
      
      // Search Function
      function SearchDate(dSel, mSel, ySel, body, manager){
        var from = new Date(mSel.value+"/"+dSel.value+"/"+ySel.value);
        var to = new Date(from); to.setDate(to.getDate()+1); to.setMilliseconds(to.getMilliseconds()-1);
        manager.ShowingDate = from
        manager.GetEventList(from, to, function(body, date, manager, list){
          var mer = new DayEventsRenderer(manager);
          mer.Render(body, list);
        }.Bind(this, body, from, manager));
      }  
            
      Object.SetProperties(btnGo, {onclick:SearchDate.Bind(this, dSel, mSel, ySel, body, this.EManager)});

      
      // Create Calendar Division
      var div = Object.NewTagInto(body, "div", {style:{position:'relative', display:'block', width:'100%', height:'92%', overflow:'hidden', border:'1px solid gray', padding:'0px 0px 0px 0px'}});;

      // Calculate Event Label Position 
      var listPos = new Array();
      for(var i=0; i<list.length; i++)
         listPos.push({Event:list[i], Pos:{Top:1, Div:1}});
      
      var max=0, md=1;
      while(max<md){
        max++;
        var rItem = null;
        for(var i=0; i<listPos.length; i++)
        {
           var cItem = listPos[i];
           rItem = (rItem==null && cItem.Pos.Top==max?cItem:rItem);
           if(rItem!=null && cItem.Pos.Top==max && cItem!=rItem)
           {
           
             var t1 = new Date(rItem.Event.From); t1.setHours(t1.getHours(),0,0,0);
             var t2 = new Date(rItem.Event.To); t2.setHours(t2.getHours()+1,0,0,0); //t2.setDate(t2.getDate()+1);
             
             var t4 = new Date(cItem.Event.From); t4.setHours(t4.getHours(),0,0,0); //t4.setDate(t4.getDate()+1);
             
             if(new Range(t1, t2, true, true).IsCover(t4))             
             {
               cItem.Pos.Top++;
               md=cItem.Pos.Top+1;
             }
             else
               rItem = cItem;
           }           
        } 
      }
      
      for(var i=0; i<listPos.length; i++)
        listPos[i].Pos.Div = md;
      
      var manager = this.EManager;
      var eList = listPos;
      var maxShow = settings.MaxEventRow;
      var conHeight = div.clientHeight;
      var conWidth = div.clientWidth;

      var totalHour = 24;
      var unitHour = 1;
      var totalRow = settings.ShowingDayRow;
      
      var totalCol = totalHour / unitHour / totalRow;
      
      var conActHeight = conHeight-(conHeight%totalRow);
      var conActWidth = conWidth-(conWidth%totalCol);
      
      var rHeight = conActHeight/totalRow;
      var rWidth = conActWidth/totalCol;  
      var rMargin = 2;
      
      var mHeadHeight = 15;
      var mFootHeight = 15;
      var mBodyHeight = rHeight - mHeadHeight - mFootHeight;
      
      var lHeight = (mBodyHeight-((mBodyHeight%maxShow==0?0:mBodyHeight%maxShow)))/maxShow;
      var lFontSize = lHeight-(rMargin*3);
      
      var dayEventInDiffWeek = {};
      var lLabelArrowWidth = 12;
      var lLabelTextFrontMargin = 2;
      
      Object.SetProperties(div, {style:{width:conActWidth+"px", height:conActHeight+"px"}})
      for(var i=0; i<totalRow; i++)
      {
        var row = Object.NewTagInto(div, "div", {style:{position:'relative', top:'0px', display:'block', left:((rWidth*totalCol)*i*-1)+'px', width:(totalCol*rWidth)+'px', height:rHeight+'px', styleFloat:'left', cssFloat:'left', margin:'0px 0px 0px 0px'}}); 
        var ul  = Object.NewTagInto(row, "ul" , {style:{position:'relative', left:'0px', listStyle:'none', padding:'0px', margin:'0px 0px 0px 0px', height:rHeight+'px', styleFloat:'left', cssFloat:'left'}}); 

        var ssDate=new Date(sDate); ssDate.setHours(i*totalCol);//.setMonth((i*(totalCol/totalRow)));
        var eeDate=new Date(ssDate); eeDate.setHours((i+1)*(totalCol));//.setMonth(eeDate.getMonth()+(totalCol/totalRow));
        
        var rowRange = new Range(ssDate, eeDate, true, true); 
         
        for(var cdate=new Date(sDate); yearRange.IsCover(cdate); cdate.setHours(cdate.getHours()+unitHour))
        {
          var li    = Object.NewTagInto(ul, "li", {style:{left:'0px', top:'0px', borderTop:'1px gray solid', borderLeft:'1px gray solid', width:(rWidth-1)+'px', height:rHeight+'px', styleFloat:'left', cssFloat:'left'}});
          var mHead = Object.NewTagInto(li, "div", {}); Object.SetProperties(mHead, styles.GetStyle("Header"));
                      Object.NewTagInto(mHead, "div", {innerHTML:(cdate.getHours().toString().length==1?"0":"")+cdate.getHours()+"-" + ((cdate.getHours()+unitHour).toString().length==1?"0":"")+(cdate.getHours()+unitHour), style:{height:mHeadHeight+'px'}, 
                                                       onclick:function(date, manager){manager.ShowingDate = date; manager.EventCalendar.TabContainer.FocusToTab("Month");}.Bind({}, new Date(cdate), this.EManager)});

          var mBody = Object.NewTagInto(li, "div", {}); 
                      Object.SetProperties(mBody, styles.GetStyle("Today"));

          var hourStart = cdate;
          var hourEnd = new Date(cdate); hourEnd.setHours(hourEnd.getHours()*unitHour);//hourEnd.setMonth(hourEnd.getMonth()+1);
          var hourDay = new Range(hourStart, hourEnd, true, false);

          var matches = eList.GetMatches(function(item){       
            var r1 = new Range(item.Event.From, item.Event.To, true, false);
            return !r1.IsBefore(hourDay) && !r1.IsAfter(hourDay);
          });
                    
          if(matches.length>maxShow)
          {            
            var lblMore = Object.NewTagInto(mBody, "a", {innerHTML:labels.More, href:'javascript:void(0)', style:{position:'relative', height:mFootHeight+'px', fontSize:(mFootHeight-3)+'px', top:mBodyHeight+'px', styleFloat:'right', cssFloat:'right'}
            }); 
             
            new MoreEventRenderer(lblMore, labels.EventOnHour, matches, styles.GetStyle("MoreToolTip"));  
          }
          

        }
 
              
        var parent = this;
        
        var evtCloseFrom = new Date(sDate); evtCloseFrom.setHours(evtCloseFrom.getHours()-1)
        var evtCloseTo   = new Date(sDate); evtCloseTo.setDate(evtCloseTo.getDate()+1); evtCloseTo.setHours(evtCloseTo.getHours()+1);
        
        eList.Foreach(function(item){
        
          var evt = item.Event;
          var pos = item.Pos;
          var evtHourFrom = new Date(item.Event.From<evtCloseFrom?evtCloseFrom:item.Event.From); //evtHourFrom.setHours(evtHourFrom.getHours(),0,0,0);  //new Date(item.Event.From);               
          var evtHourTo   = new Date(item.Event.To  >evtCloseTo  ?evtCloseTo  :item.Event.To);  //evtCloseTo.setHours(evtCloseTo.getHours()+1,0,0,0); //new Date(item.Event.To);
          
          var lWidth = parent.CoverHour(evtHourTo, evtHourFrom, unitHour) * rWidth; 
              lWidth = lWidth - ((rMargin+1)*2); // 1 is border// and 2 is margin
          
          var lTop = mHeadHeight + rMargin + ((item.Pos.Top-1) * (lHeight));
          var lLeft = rMargin + (evtHourFrom>sDate?1:-1)*(parent.HourDistance(evtHourFrom, sDate, unitHour)*rWidth);
          
          var lblEvt = Object.NewTagInto(row, "span", {style:{top:lTop+"px", left:lLeft+"px", height:(lHeight-(rMargin*2))+"px", width:lWidth+"px", display:item.Pos.Top>maxShow?'none':'block', filter:"alpha(opacity=75)", opacity:'0.75', border:'1px solid gray', position:"absolute", cursor:'pointer',  overflow:'hidden', textAlign:'left', /*fontSize:lFontSize+'px',*/ styleFloat:'left', cssFloat:'left', clear:'left'}});
          
          new EventDetailRenderer(evt, manager, lblEvt);
    
          Object.SetProperties(lblEvt, styles.GetStyle("GeneralLabel"));
                   
          if(!dayEventInDiffWeek[evt.ID])
            dayEventInDiffWeek[evt.ID] = new Array();
          dayEventInDiffWeek[evt.ID].push(lblEvt);
          
          Object.SetProperties(lblEvt, {
            onmouseover:function(list, sty){
              list.Foreach(function(lbl){
                Object.SetProperties(lbl, sty, {style:{filter:"alpha(opacity=100)", opacity:'1.00'}});
              });
            }.Bind(lblEvt, dayEventInDiffWeek[evt.ID], styles.GetStyle("FocusLabel")),
            onmouseout:function(list, sty){
              list.Foreach(function(lbl){
                Object.SetProperties(lbl, sty, {style:{filter:"alpha(opacity=75)", opacity:'0.75'}});
              });
            }.Bind(lblEvt, dayEventInDiffWeek[evt.ID], styles.GetStyle("GeneralLabel"))
          });
          
          var lblEvtLeftArrow=null;
          var lblEvtRightArrow=null;
          var lblDist = lLabelArrowWidth;  
          
          
          
          var rangeL = new Range(evtHourFrom, evtHourTo, false, true);
          if(rangeL.IsStepIn(rowRange) || rangeL.IsCover(rowRange))
          {
             lblEvtLeftArrow = Object.NewTagInto(lblEvt, "span", {innerHTML:"&#9668;", style:{color:'black', fontWeight:'bolder', position:'relative', left:'0px', overflow:'hidden', fontSize:'12px', width:lLabelArrowWidth}});
             var dist = rWidth  * parent.CoverHour(rowRange.Min, rangeL.Min, unitHour)- rMargin;
             lblEvtLeftArrow.style.left = (dist) + "px";
             
             lblDist-=lLabelArrowWidth;
          }
          
          var rangeR = new Range(evtHourFrom, evtHourTo, true, false);
          if(rangeR.IsStepOut(rowRange) || rangeR.IsCover(rowRange))
          {
             lblEvtRightArrow = Object.NewTagInto(lblEvt, "span", {innerHTML:"&#9658;", style:{color:'black', fontWeight:'bolder', position:'relative', left:'0px', overflow:'hidden', fontSize:'12px', width:lLabelArrowWidth}});
             var dist = rWidth * parent.CoverHour(rowRange.Max, rangeR.Min, unitHour);
             lblEvtRightArrow.style.left = (dist-lLabelArrowWidth-(lblEvtLeftArrow==null?0:lLabelArrowWidth)) + "px";
             
             lblDist-=lLabelArrowWidth;
          }
          
          var eventRange = new Range(evtHourFrom, evtHourTo, true, true);
          if(rangeL.IsStepIn(rowRange) || eventRange.IsCover(rowRange))
            lblDist +=  (parent.CoverHour(rowRange.Min, eventRange.Min, unitHour) * rWidth) ;
            
          var lblText = Object.NewTagInto(lblEvt, "span", {innerHTML:(item.Event.URL==""?"":"<a href='" + item.Event.URL + "' target='_blank'><img src='" + settings.UrlImage + "' border='0' height='80%'></a> ") + item.Event.Title, style:{position:'relative', left:'0px'}});
          lblText.style.left = lblDist+"px";
          
          new ToolTipEventRender(lblEvt, evt, styles.GetStyle("EventToolTip"), manager.Labels.Tooltip);

              
        });
         

      }
      
   
   }   
});
