﻿

Type.registerNamespace("ArtfulBits.CalendarPro");
ArtfulBits.CalendarPro.CalendarProWebPart = function( element )
{
    ArtfulBits.CalendarPro.CalendarProWebPart.initializeBase(this, [element]);
    
    this.id = this.get_id();    
    this.name = element.id;
    this.viewType = "month";
    
    this.allowEditItemTitle = false;
    this.allowDragItem = false;
    this.allowResizeItem = false;
    this.allowDeleteItem = false;
    this.allowAddItem = false;
    
    this._startHour = -1;
	this._endHour = -1;
	this._slotsPerHour = -1;
	
	this._firstDate = new Date();
	
	this._rootTable = null;
	
	this._items = {};
	
	this._editImageSrc = "/_layouts/images/edititem.gif";
	this._deleteImageSrc = "/_layouts/images/delitem.gif";
	
	this._confirmDeleteMesage = "Are you sure you want to send this item to the site Recycle Bin?";
	this._clickToAddAppointment = "click to add appointment";
	this._clickToAddAllDayAppointment = "click to add event";
	this._titleEditItem = "Edit Item";
	this._titleDeleteItem = "Delete Item";
	
	this._isEditing = false;
	this._isDragging = false;
	this._isResizing = false;
}

ArtfulBits.CalendarPro.CalendarProWebPart.prototype = 
{
    initialize : function(){
        ArtfulBits.CalendarPro.CalendarProWebPart.callBaseMethod(this, "initialize");

		this._initGridCell();
        this._attachEvents(true);
    },
    dispose : function(){        
        ArtfulBits.CalendarPro.CalendarProWebPart.callBaseMethod(this, "dispose");
        this._disposeAddAppointmentButton();
        this._attachEvents(false);
        this.editData = null;
    },
    
    set_firstDate : function( dt ){
		this._firstDate = dt;
    },

	get_firstDate : function(){
		return this._firstDate;
    },
    
    set_items : function( items ){
		this._items = items;
    },
	get_items : function(){
		return this._items;
    },
    
    postback : function( arg ){
        var sArg = arg;
        if( ( typeof( arg ) == "object" )&& arg.length )
        {   
            sArg = "";         
    		for( var i = 0; i < arg.length; ++i)
    		{
    			if( i != 0 )
    			{
    				sArg += ",";
    			}
    			sArg += arg[i];
    		}
        }
        __doPostBack( this.name, sArg );
    },
    
    isMonthView : function(){
        return (this.viewType == "month");
    },
    isDayView : function(){
        return (this.viewType == "day");
    },
    isWeekView : function(){
        return (this.viewType == "week");
    },
    
    _getAppClass : function(){
        var sRes = "";
        if( this.isMonthView() ){
            sRes = "ms-cal-monthitem";
        }
        else if( this.isWeekView() ){
            sRes = "ms-cal-tweekitem";
        }
        else if( this.isDayView() ){
            sRes = "ms-cal-tdayitem";
        }
        return sRes;
    },
    
    _getJQueryAppClassSelector : function(){
        var sRes = "." + this._getAppClass();        
        return sRes;
    },
    
    _getRootTable : function(){
    	if( null == this._rootTable )
    	{
    		this._rootTable = jQuery( ".ms-cal-gempty" )[0];
    	}
		return this._rootTable;
    },
    
    _initGridCell : function(){
    	var rootTbl = this._getRootTable();
    	var nStartIdx = this._getHeaderRowsCount();

    	for( var i = nStartIdx; i < rootTbl.rows.length; i++ )
    	{
    		var oTimeTD = rootTbl.rows[i].cells[1];
    		var sHour = jQuery(oTimeTD).text();
//    		sHour = sHour.substring(0,2));
			var nHour = parseInt(nHour, 10);
			if( -1 != sHour.toLowerCase().indexOf( "am" ) )
			{
			    sHour = sHour.substring(0,2);			    
			    nHour = parseInt( sHour, 10 );
                if( 12 == nHour )
                {
                    nHour = 0;
                }
			}
			if( !isNaN( nHour ) )
			{
				this._startHour = nHour;
				break;
			}
    	}
    	
    	for( var i = rootTbl.rows.length - 1; i > 0; i-- )
    	{
    		var oTimeTD = rootTbl.rows[i].cells[1];
    		var sHour = jQuery(oTimeTD).text();			
			if( -1 != sHour.toLowerCase().indexOf( "pm" ) )
			{
			    sHour = sHour.substring(0,2);
            }
            var nHour = parseInt( sHour, 10)
			if( !isNaN( nHour ) )
			{
				this._endHour = ( nHour < 12 ) ? (nHour+12) : nHour;
				this._slotsPerHour = rootTbl.rows.length - i;
				break;
			}
    	}
    },

    _getWeekData : function( offset, offsetRoot ){        
        var nIdx = -1;
        var nWeekHeight = 0;
        var nWeekTop = 0;
        
        var oRootTbl = this._getRootTable();
        var nStartIdx = this._getHeaderRowsCount();
	    var nWeekIdx = -1;
	    var oWasteOffset = this._getWasteOffset();	    
	    var nOffsetTop = 0;
		for( var i = nStartIdx; i < oRootTbl.rows.length; )
		{
		    var row = oRootTbl.rows[i];
		    var nHeight = row.offsetHeight;
		    var nextRow = oRootTbl.rows[i + 1];
		    if( ( null != nextRow ) )
		    {
		        var cell = nextRow.cells[0];
		        var rowSpan = parseInt( jQuery( cell ).attr("rowSpan"), 10 );
		        if( !isNaN( rowSpan ) &&( 1 < rowSpan ) )
		        {
		            nWeekIdx ++;
		            i += rowSpan;
		            nHeight += cell.offsetHeight;
                }
            }
            
            var nTop = nOffsetTop + offsetRoot.top + oWasteOffset.top;
	        if( ( nTop <= offset.top )&&
			    ( offset.top < nTop + nHeight ) )
		    {
			    nIdx = nWeekIdx;
			    nWeekHeight = nHeight - row.offsetHeight;
			    nWeekTop = nTop + row.offsetHeight;			    
			    break;
		    }
		    else
		    {
		        if( offset.top < nTop )
		        {
		            break;
		        }
		        nOffsetTop += nHeight;
		    }
            i++;
		}
    			
        var res = { Index : nIdx, Height : nWeekHeight, Top : nWeekTop };
        return res;
    },
    
    _ensureCellData : function( cell ){
        if( ( null == cell.CellData )&&( null !== cell.CellData ) )
        {
            var oRootTbl = this._getRootTable();
            var offsetRoot = jQuery(oRootTbl).offset();
            var offsetCell = jQuery(cell).offset();            
            var date = this._getDateByOffset( offsetCell, true, offsetRoot );
            var bAllDay = false;
            if( null != date )
            {
                bAllDay = this._isOverAllDayEvents( offsetRoot, offsetCell ) || this.isMonthView();            
                cell.CellData = { Date : date, AllDay : bAllDay };
            }
        }
        if(!cell.CellData)
        {
            cell.CellData = null;
        }
        return cell.CellData;
    },
    
    _isCellDataEqual : function( cellData1, cellData2 ){
        var res = cellData1 == cellData2;
        if( !res )
        {
            if( ( null != cellData1 )&&( null != cellData2 ) )
            {                
                res =( cellData1.AllDay == cellData2.AllDay )&&
                    ( cellData1.Date.toString() == cellData2.Date.toString() );                
            }
        }
        return res;
    },
    
    _getDateByOffset : function( offset, allowAllDay, offsetRoot ){
    	var date = null;
    	var oRootTbl = this._getRootTable();
    	if(!offsetRoot)
    	{    	
    	    offsetRoot = jQuery(oRootTbl).offset();
        }

        var bOverDateContent = this._isOverTableDateContent( offsetRoot, offset );
    	var bOverAllDayContent = allowAllDay && this._isOverAllDayEvents( offsetRoot, offset );
    	if( bOverDateContent || bOverAllDayContent )
    	{
    		var nOffsetTop = 0;
    		var nRowIdx = -1;
    		if( this.isMonthView()  )
    		{
    		    var week = this._getWeekData( offset, offsetRoot );
    		    nRowIdx = week.Index;
    		}
    		else
    		{
    		    if( !bOverAllDayContent )
    		    {
	    		    for( var i = 0; i < oRootTbl.rows.length; ++i )
		    	    {
		    		    var nRowHeight = oRootTbl.rows[i].offsetHeight;
		    		    var nTop = nOffsetTop + offsetRoot.top;
		    		    if( ( nTop <= offset.top )&&
		    			    ( offset.top < nTop + nRowHeight ) )
		    		    {
		    			    nRowIdx = i;
		    			    break;
		    		    }
		    		    else
		    		    {
		    			    nOffsetTop += nRowHeight;
		    		    }
				    }
				    nRowIdx -= this._getHeaderRowsCount();
                }
	    	}
	    	if( bOverAllDayContent ||( 0 <= nRowIdx ) )
	    	{
	    		var nColumnIdx = -1;
	    		var row = oRootTbl.rows[0];
	    		if( this.isDayView() )
	    		{
	    			var nLeft = row.cells[0].offsetWidth + row.cells[1].offsetWidth;
	    			if( nLeft + offsetRoot.left <= offset.left )
		    		{
		    			nColumnIdx = 2;
		    		}
	    		}
	    		else
	    		{
	    			var nOffsetLeft = 0;
		    		for( var i = 0; i < row.cells.length; ++i )
			    	{
			    		var nCellWidth = row.cells[i].offsetWidth;
			    		nLeft = nOffsetLeft + offsetRoot.left;
			    		if( ( nLeft <= offset.left )&&
			    			( offset.left < nLeft + nCellWidth ))
			    		{
			    			nColumnIdx = i;
			    			break;
			    		}
			    		else
			    		{
			    			nOffsetLeft+= nCellWidth;
			    		}
					}
	    		}
	    		
	    		if( 2 <= nColumnIdx  )
	    		{
	    		    var dayColumn = nColumnIdx - 2;
	    		    var firstDate = this.get_firstDate();
	    			if( this.isMonthView()  )
		    		{
		    			var delta = nRowIdx * 7 + dayColumn;
		    			date = new Date( firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate()+ delta, 0, 0, 0 );
		    		}
		    		else
		    		{
		    			var nHour = bOverAllDayContent ? 0 : parseInt( nRowIdx / this._slotsPerHour , 10 ) + this._startHour;
		    			var nMinutes = bOverAllDayContent ? 0 :( nRowIdx % this._slotsPerHour ) * ( 60 / this._slotsPerHour );
		    					    			
		    			date = new Date( firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + dayColumn, nHour, nMinutes, 0 );
		    		}
				}
	    	}
    	}
		return date;
    },    
    
    _getDateCellData : function( date, bAllDay, dateOffset, rootOffset, offsetWaste ){
        var oRootTbl = this._getRootTable();
    	if( !rootOffset )    	
            rootOffset = jQuery( oRootTbl ).offset();
            
        if( !offsetWaste )
            offsetWaste = this._getWasteOffset();
            
        var nLeft = 0;
	    var nWidth = 0; 		
	    var nTop = rootOffset.top;
	    var nHeight = 0;
	    
	    if( this.isMonthView() )
        {
            var week = this._getWeekData( dateOffset, rootOffset );
            nHeight = week.Height;
            nTop = week.Top;
        }
        else
        {
	        if( bAllDay )
	        {
	           nTop = this._getWasteOffset( true ).top + rootOffset.top;
	           nHeight = this._getAllDayAreaHeight();
	        }
	        else
	        {
	            var nRowIdx = ( date.getHours() - this._startHour )*this._slotsPerHour + parseInt((date.getMinutes()*this._slotsPerHour)/60,10) + this._getHeaderRowsCount();
	            for( var i =0; i < nRowIdx; ++i )
	            {
		            nTop += oRootTbl .rows[i].offsetHeight;
	            }
	            
	            nHeight = oRootTbl.rows[nRowIdx].offsetHeight;
            }
        }
	    if( this.isDayView() )
	    {
		    nLeft = rootOffset.left + offsetWaste.left;
		    nWidth = oRootTbl.offsetWidth - offsetWaste.left;
	    }
	    else if( this.isWeekView() || this.isMonthView() )
	    {
	        var nColumnIdx = this._getDaysDelta( this.get_firstDate(), date );
	        if( this.isMonthView() )
	        {
	            nColumnIdx = nColumnIdx % 7;
            }
	        
		    nLeft = rootOffset.left + offsetWaste.left;
		    var row = oRootTbl.rows[0];
		    for( var i = 0; i < nColumnIdx; ++i )
		    {
			    nLeft += row.cells[ i + 2 ].offsetWidth;
		    }
		    nWidth = row.cells[ nColumnIdx + 2 ].offsetWidth;
	    }
	    
	    return { Top : nTop, Left : nLeft, Width : nWidth, Height : nHeight };
    },
    
    _isOverAllDayEvents : function( offsetRoot, offset ){
        var bRes = false;
        if( !this.isMonthView() )
        {
    	    var oRootTbl = this._getRootTable();
    	    var nAllDayCount = this._getAllDaysRowsCount();
    	    if( ( 0 < nAllDayCount) &&
    	        this._isInRange( offsetRoot, offset, { height: oRootTbl.offsetHeight, width: oRootTbl.offsetWidth } ) )
            {
    		    var row = oRootTbl.rows[0];
    	        var offsetWaste = this._getWasteOffset( true );
			    bRes = this._isInRange( 
				    { top : offsetRoot.top + offsetWaste.top, left : offsetRoot.left + offsetWaste.left },
				     offset,
				     { height: this._getAllDayAreaHeight(), width: oRootTbl.offsetWidth - offsetWaste.left } );
    	    }
    	}
    	return bRes;
    },
    
    _getAllDayAreaHeight : function(){
        var nRes = 0;
        var oRootTbl = this._getRootTable();
        var nAllDayCount = this._getAllDaysRowsCount();
        var nTitleRowsCount = this._isDayHeaderVisible() ? 1 : 0;
	    for( var i = 0; i < nAllDayCount; ++i )
	    {
	        nRes += oRootTbl.rows[i + nTitleRowsCount].offsetHeight;
	    }
	    return nRes;
    },

    _isOverTableDateContent : function( offsetRoot, offset ){
    	var bRes = false;
    	var oRootTbl = this._getRootTable();
    	if( this._isInRange( offsetRoot, offset, { height: oRootTbl.offsetHeight, width: oRootTbl.offsetWidth } ) ){
    		var offsetWaste = this._getWasteOffset();
			bRes = this._isInRange( 
				{ top : offsetRoot.top + offsetWaste.top, left : offsetRoot.left + offsetWaste.left },
				 offset,
				 { height: oRootTbl.offsetHeight - offsetWaste.top , width: oRootTbl.offsetWidth - offsetWaste.left } );
    	}
    	return bRes;
    },
 
    _getWasteOffset : function( bAllowAllDay ){
    	var oRootTbl = this._getRootTable();
    	var row = oRootTbl.rows[0];
    	var nTimeLeft = row.cells[0].offsetWidth + row.cells[1].offsetWidth;
    	var nHeaderTop = 0;
    
        var nCount = ( bAllowAllDay || this.isMonthView() ) ?
            ( this._isDayHeaderVisible() ? 1 : 0 ) :  this._getHeaderRowsCount();
    	for( var i = nCount - 1; 0 <= i; i-- )
    	{
    		var row = oRootTbl.rows[i];
    		nHeaderTop += row.offsetHeight;
    	}
    	return { top : nHeaderTop, left : nTimeLeft };
    },

    _isInRange : function( offset, offset1, delta ){
    	var bRes = ( offset.top <= offset1.top )&&    	
	    	( offset.top + delta.height > offset1.top )&&
	    	( offset.left <= offset1.left )&&
	    	( offset.left + delta.width > offset1.left );
		return bRes;
    },

    _isDayHeaderVisible : function(){
    	if( null == this.isDayHeaderVisible )
    	{
    	    var rootTable = this._getRootTable();
    		this.isDayHeaderVisible = 0 < jQuery(rootTable).find( ".ms-cal-wtopdayL,.ms-cal-wtopday,.ms-cal-wtopday-today,.ms-cal-weekname").length;
    	}
    	return this.isDayHeaderVisible;
    },
   
    _getHeaderRowsCount : function(){
    	var nRes = this._getAllDaysRowsCount();
    	if( this._isDayHeaderVisible() )
    		nRes++;
		return nRes;
    },

    _getAllDaysRowsCount : function(){
        if( null == this._allDaysRowsCount )
        {
            this._allDaysRowsCount = 0;
            if( !this.isMonthView() )
            {
                var rootTbl = this._getRootTable();
                var nStart = this._isDayHeaderVisible() ? 1 : 0;
                var sAppClasses = this._getAllDayJQuerySelectors();            
                for( var i = nStart; i < rootTbl.rows.length; ++i )
                {
                    if( 0 < jQuery(rootTbl.rows[i]).find( sAppClasses).length )
                    {
                        this._allDaysRowsCount++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        return this._allDaysRowsCount;        
    },

    _isAppAllDay : function( oEl ){        
        return ( -1 != Array.indexOf( this._getAllDayAppClass(), oEl.className ) );
    },
    
    _getAppDragEl : function(el){
        var res = el;
        if( this._isAppAllDay(el) ){
            res = this._getAllDayAppContent( el );
        }
        else if( this.isMonthView() ){
            res = el.parentNode.parentNode.parentNode;
        }
        return res;
    },
    
    _getAllDayAppContent : function(el){
        return this.isMonthView() ? el : el.getElementsByTagName("DIV")[0];
    },

    _getAllDayJQuerySelectors : function(){
        var res = "";
        var arrClasses = this._getAllDayAppClass();
        for( var i = 0; i < arrClasses.length; ++i )
        {
            if( 0 != i )
            {
                res += ",";
            }
            res += "." + arrClasses[i];
        }
        return res;
    },

    _getAllDayAppClass : function(){
        var res = ["ms-cal-walldayeventL","ms-cal-walldayevent","ms-cal-alldayeventL","ms-cal-alldayevent", "ms-cal-muworkitem" ];
        if( this.isMonthView() )
        {
            res.push("contB");
        }
        return res;
    },
    
    _isDayCell : function( cell ){
    	var bRes = false;
    	if( cell &&( cell.tagName == "TD" ))
    	{
    		var tr = cell.parentNode;
    		var oParTbl = tr.parentNode.parentNode;
    		if( oParTbl == this._getRootTable() )
    		{
    			bRes = ( this._getHeaderRowsCount() <= Array.indexOf( oParTbl.rows, tr ) )&&
    				( 2 <= Array.indexOf( tr.cells, cell ) );
    		}
    	}
    	return bRes;
    },
    
    createDelegate : function( fn, arg )
    {        
        var self = this;
        return function()
        {
            var args = null;
            if( null == arg )
            {
                args = arguments;
            }
            else
            {
                args = [];
                if( arg && arg.length )
                {
                    for(var i = 0; i < arg.length; i++ )
                    {
                        args.push(arg[i]);
                    }
                }
                for(var i = 0; i < arguments.length; i++ )
                {
                    args.push(arguments[i]);
                }
            }
            
            return fn.apply(self,args)
        };
    },
    
	_attachEvents : function( bAdd ){
	    var arrApps = jQuery(this._getRootTable()).find( this._getJQueryAppClassSelector() + "," + this._getAllDayJQuerySelectors() );
        var fnHandler = bAdd ? "bind" : "unbind";
        if( arrApps && arrApps.length )
        {
            for( var i = 0; i < arrApps.length; ++i )
            {
            	var app = arrApps[i];
//            	if( !this._isRecurrenceItem( app ) )
            	{
            	    var jQueryApp = jQuery( app );
            	    if( bAdd )
            	    {
            		    app._mouseDownHandler = this.createDelegate( this._onAppMouseDown, [app] );
            		    jQueryApp.bind( "mousedown", app._mouseDownHandler);
            		    
            		    app._mouseOverHandler = this.createDelegate( this._onAppMouseOver, [app]);
            		    jQueryApp.bind("mouseenter", app._mouseOverHandler );
            		    
            		    app._mouseOutHandler = this.createDelegate( this._onAppMouseOut, [app]);
            		    jQueryApp.bind("mouseleave", app._mouseOutHandler );
            		    
            		    this._ensureCreateIcons( app );
				    }
				    else
				    {
				        jQueryApp.unbind( "mousedown", app._mouseDownHandler);
            		    app._mouseDownHandler = null;
            		    
            		    jQueryApp.unbind("mouseenter", app._mouseOverHandler );
            		    app._mouseOverHandler = null;
            		    
            		    jQueryApp.unbind("mouseleave", app._mouseOutHandler );
            		    app._mouseOutHandler = null;
            		    
            		    this._disposeIcons( app );
				    }
    				
				    if( bAdd )
				    {
				        if( this.isMonthView() && !this._isAppAllDay( app ) )
				        {
				            if( app.tagName == "TD" )
				            {
				                var tbl = app.parentNode.parentNode.parentNode;
				                tbl.style.width = "99%";
				            }
				        }
					    if( this._isItemResizeEnabled(app) && !this.isMonthView() && !this._isAppAllDay( app ) )
					    {					        
						    var cont = app.rows[0].cells[0];
    						
						    var childDiv = cont.getElementsByTagName("div")[0];
						    var nWidth = childDiv.offsetWidth;
    						
						    var borderTopEl = this._createBorderEl( true );
						    borderTopEl.style.width = nWidth + "px";
						    cont.insertBefore( borderTopEl, cont.childNodes[0] );
    						
						    var borderBottomEl = this._createBorderEl( false );
						    borderBottomEl.style.width = nWidth + "px";
						    cont.appendChild(borderBottomEl);
    						
						    app.borders = [ borderTopEl, borderBottomEl ];
					    }
				    }
    				
				    if( app.borders && app.borders.length )
				    {
					    for( var j = 0; j < app.borders.length; ++j )
					    {
						    var border = app.borders[j];
						    var jQueryBorderEl = jQuery(border);
						    if( bAdd )
						    {						        
		            		    border._mouseDownHandler = this.createDelegate( this._onAppBorderMouseDown, [app, border]);
		            		    jQueryBorderEl.bind("mousedown", border._mouseDownHandler);
						    }
						    else
						    {
		            		    jQueryBorderEl.unbind("mousedown", border._mouseDownHandler);
		            		    border._mouseDownHandler = null;	            		
						    }
					    }
					    if(!bAdd)
					    {
						    app.borders = null;
					    }
				    }
                }
            }
        }
        
        if( this.allowAddItem )
        {
            var rootTable = this._getRootTable();
            var jQueryTable = jQuery(rootTable);
            if( bAdd )
            {
                jQueryTable.bind( "mouseover", Function.createDelegate( this, this._rootTableMouseOver ) );
                jQueryTable.bind( "mouseout",Function.createDelegate( this, this._rootTableMouseOut ) );
            }
            else
            {
               jQueryTable.unbind( "mouseover", Function.createDelegate( this, this._rootTableMouseOver ) );
               jQueryTable.unbind( "mouseout",Function.createDelegate( this, this._rootTableMouseOut ) );
            }
        }
    },
    
    ////////////////////////////////////////////////////////////////////////
    ///// Adding events
    
    _ensureCreateAddAppointmentButton : function(){
        if( this.btnAddEvent == null )
        {
            var btn = document.createElement( "div" );
            this.btnAddEvent = btn;
            btn.innerHTML = "<table height='100%' width='100%' cellpadding=0 cellspacing=0><tr><td><span></span></td></tr></table>";            
    	    var st = btn.style;
    	    st.top = "0px";
    	    st.left = "0px";
    	    st.width = "200px";
    	    st.height = "20px";
    	    st.overflow = "hidden";
    	    st.position = "absolute";
    	    st.visibility = "hidden";
    	    st.backgroundColor = "#FFFFFF";
    	    document.body.appendChild( btn );
    	    if( this.isMonthView() )
    	    {
    	        btn.className = "contB";
    	        btn.getElementsByTagName("TABLE")[0].className = "ms-cal-muworkitem";    	        
    	    }
    	    else
    	    {    	    
    	        btn.className = this._getAppClass();
    	    }    	    
    	    var jQueryBtn = jQuery( btn );
    	    btn._mouseOverHandler = this.createDelegate( this._onAddAppButtonMouseOver );
            jQueryBtn.bind("mouseenter", btn._mouseOverHandler );
            btn._mouseOutHandler = this.createDelegate( this._onAddAppButtonMouseOut );
            jQueryBtn.bind("mouseleave", btn._mouseOutHandler );
            btn._clickHandler = this.createDelegate( this._onAddAppButtonClick );
            jQueryBtn.bind("click", btn._clickHandler );
    	    this.btnAddEventContent = this.btnAddEvent.getElementsByTagName("SPAN")[0];
    	    var td = this.btnAddEvent.getElementsByTagName("TD")[0];
    	    td.style.verticalAlign = "middle";
    	    td.style.textAlign = "center";
    	    td.style.whiteSpace = "nowrap";
        }
        return this.btnAddEvent;
    },
    
    _disposeAddAppointmentButton : function(){
        if( null != this.btnAddEvent )
        {
            var btn = this.btnAddEvent;                        
            var jQueryBtn = jQuery( btn );    	    
            jQueryBtn.unbind("mouseenter", btn._mouseOverHandler );
            btn._mouseOverHandler = null;
            jQueryBtn.unbind("mouseleave", btn._mouseOutHandler );
            btn._mouseOutHandler = null;            
            jQueryBtn.unbind("click", btn._clickHandler );
            btn._clickHandler = null;
            
            this.btnAddEvent.parentNode.removeChild(this.btnAddEvent);
            this.btnAddEvent = null;
            this.btnAddEventContent = null;
        }
    },
    
    _rootTableMouseOver : function(ev){
        var rootTable = this._getRootTable();
        
        var cell = this._getTargetTableCell(ev);
        if( cell )
        {            
            var cellData =this._ensureCellData( cell );
            var prevCellData = this.previousHoverCellData;
            if( null == cellData )
            {
                if( null != this.previousHoverCell )
                {
                    this._cellMouseOut(this.previousHoverCell);                    
                }
            }
            else
            {
                if( null == prevCellData )
                {
                    this._cellMouseOver( cell );
                }
                else
                {
                    if( this.timerCellMouseOut )
                    {
                        window.clearTimeout( this.timerCellMouseOut );
                        this.timerCellMouseOut = null;
                    }
                    if( !this._isCellDataEqual(prevCellData, cellData) )
                    {
                        this._cellMouseOut( this.previousHoverCell );
                        this._cellMouseOver( cell );
                    }
                }
            }
            this.previousHoverCellData = cellData;
            this.previousHoverCell = ( null != cellData ) ? cell : null;
        }
    },
    
    _rootTableMouseOut : function(ev){
        var rootTable = this._getRootTable();
        var cell = this._getTargetTableCell(ev);
        if( cell )
        {
            /*
            var cellData = this._ensureCellData( cell );
            if( !this._isCellDataEqual(this.previousHoverCellData, cellData) )
            {
                if( null != this.previousHoverCell )
                {
                    this._cellMouseOut( this.previousHoverCell );
                }            
            }
            */
            this.timerCellMouseOut = window.setTimeout(  this.createDelegate( this._cellMouseOut, [cell] ), 100 );
        }
    },
    
    _hideAddEventButton : function(){        
        if(this.btnAddEvent)
        {
            this.btnAddEvent.style.visibility = "hidden";
        }            
//        this.previousHoverCellData = null;
//        this.previousHoverCell = null;
        this.addAppointmentData = null;
    },
    
    _showAddEventButton : function( cell ){
        if( this._isEventActionInProcess() )return;        
        this._ensureCreateAddAppointmentButton();
        var stBtn = this.btnAddEvent.style;
        var cellData = this._ensureCellData( cell );
        var position = this._getDateCellData( cellData.Date, cellData.AllDay, jQuery(cell).offset() );
        stBtn.left = position.Left + "px";
        stBtn.top = position.Top + "px";
        stBtn.width = position.Width -2 + "px";
        stBtn.height = position.Height -2 + "px";
        if( cellData.AllDay )
        {
            stBtn.height = "20px";
            stBtn.top = (position.Top + position.Height - 2 - this.btnAddEvent.offsetHeight) + "px";
        }        
        stBtn.visibility = "";
        
        this.addAppointmentData = cellData;
        this.btnAddEventContent.innerHTML = cellData.AllDay ? this._clickToAddAllDayAppointment : this._clickToAddAppointment;	
    },
    
    _getIsShownAddEventButton : function(){
        return ( null != this.btnAddEvent )&&( this.btnAddEvent.style.visibility != "hidden" );
    },
    
    _cellMouseOver : function( cell ){
        if(this._isEditing && !this.allowAddItem)return;
        this.timerShowAddEventButton = window.setTimeout( this.createDelegate( this._showAddEventButton, [cell] ), 1000 );        
    },
/*    
    _addHTML : function(sVal){
        if( null == this.span )
        {
            this.span = document.createElement("div");
            this.span.style.position = "absolute";
            this.span.style.top = "0px";
            this.span.style.left = "0px";
            this.span.innerHTML = "info:<br/>";
            document.body.appendChild( this.span );
        }
        this.span.innerHTML += sVal;
    },
*/    
    _cellMouseOut : function( cell ){
        if(this._isEditing)return;
        if( this.timerShowAddEventButton )
        {
            window.clearTimeout( this.timerShowAddEventButton );
        }
        if( this.timerCellMouseOut )
        {
            window.clearTimeout( this.timerCellMouseOut );
        }
        this._hideAddEventButton();
    },
    
    _onAddAppButtonMouseOver : function(ev){        
        if( this.timerCellMouseOut )
        {
            window.clearTimeout( this.timerCellMouseOut );
            this.timerCellMouseOut = null;
        }
    },
    
    _onAddAppButtonMouseOut : function(ev){
        if(this._isEditing)return;
        this._hideAddEventButton();
    },
    
    _onAddAppButtonClick : function(ev){
        if(this._isEditing)return;
        this._startEditApp( this.btnAddEvent, "" );
    },
    
    _getTargetTableCell : function(ev){
        var res = null;
        var srcEl = ev.target;
        if( srcEl )
        {
            for( var i = 0; i < 1; i++ )
            {
                if( srcEl &&( srcEl.tagName != "TD" ) )
                {
                    srcEl = srcEl.parentNode;
                }
            }
        }
        var rootTable = this._getRootTable();
        if( srcEl &&( srcEl.tagName == "TD" ) &&( srcEl.parentNode.parentNode.parentNode == rootTable ) )
        {
            res = srcEl;
        }
        return res;
    },
    
    
    ////////////////////////////////////////////////////////////////////////
    ///// Edit & delete events
    
    _ensureCreateIcons : function( el  ){
        if( null != el.IconsData ) return;
        
        if( this._isItemDeleteEnabled(el) || this._isItemTitleEditEnabled(el) )
        {        
            var cont = ( el.tagName == "TABLE" ) ? el.rows[0].cells[0] : el;        
            var table = document.createElement( "table" );
            table.cellSpacing = "0px";
            table.cellPadding = "0px";
            table.style.position = "absolute";
            table.style.left = "-100px";
            //table.style.float = "right";
            table.style.width = "1px";
    //        jQuery( table ).css( "opacity", 0.5 );
            cont.insertBefore( table, cont.childNodes[0] );
            
            el.IconsData = { Container : table };
             
            var row = table.insertRow( 0 );
            if( this._isItemTitleEditEnabled(el) )
            {
                var cell1 = row.insertCell( 0 );
                cell1.style.padding = "2px";
                
                var imgEdit = document.createElement("img");
                imgEdit.style.cursor = "pointer";
                imgEdit.src = this._editImageSrc;
                var jQueryImgEdit = jQuery( imgEdit );
                jQueryImgEdit.css( "opacity", 0.5 );
                jQueryImgEdit.attr( "title", this._titleEditItem );
                cell1.appendChild( imgEdit );
                
                imgEdit._mouseClickHandler = this.createDelegate( this._onEditApp, [el]);
                jQueryImgEdit.bind("click", imgEdit._mouseClickHandler);
                jQueryImgEdit.bind( "mousedown", this._cancelEvent);
                jQueryImgEdit.bind( "mouseenter", this._hiliteHoverImage );
                jQueryImgEdit.bind( "mouseleave", this._unhiliteHoverImage );
                
                el.IconsData.EditImg = imgEdit;
            }
            if( this._isItemDeleteEnabled(el) )
            {
                var cell2 = row.insertCell( row.cells.length );
                cell2.style.padding = "2px";
                cell2.style.paddingLeft = "0px";
                
                var imgDel = document.createElement("img");
                imgDel.style.cursor = "pointer";
                imgDel.src = this._deleteImageSrc;
                var jQueryImgDel = jQuery( imgDel );
                jQueryImgDel.attr( "title", this._titleDeleteItem );
                jQuery( imgDel ).css( "opacity", 0.5 );
                cell2.appendChild( imgDel );
                
                imgDel._mouseClickHandler = this.createDelegate( this._onDeleteApp, [el]);
                jQueryImgDel.bind( "click", imgDel._mouseClickHandler);
                jQueryImgDel.bind( "mousedown", this._cancelEvent);
                jQueryImgDel.bind( "mouseenter", this._hiliteHoverImage );
                jQueryImgDel.bind( "mouseleave", this._unhiliteHoverImage );
                
                el.IconsData.DeleteImg = imgDel;
            }
        }
        
        return el.IconsData;
    },
    
    _disposeIcons : function(el){
        if( null == el.IconsData ) return;
        
        if( this._isItemTitleEditEnabled(el) )
        {
            var imgEdit = el.IconsData.EditImg;        
            var jQueryImgEdit = jQuery( imgEdit );
            jQueryImgEdit.unbind( "mousedown", this._cancelEvent);
            jQueryImgEdit.unbind( "click", imgEdit._mouseClickHandler);
            imgEdit._mouseClickHandler = null;
            jQueryImgEdit.unbind( "mouseenter", this._hiliteHoverImage );
            jQueryImgEdit.unbind( "mouseleave", this._unhiliteHoverImage );
        }
        if( this._isItemDeleteEnabled(el) )
        {
            var imgDel = el.IconsData.DeleteImg;
            var jQueryImgDel = jQuery( imgDel );
            jQueryImgDel.unbind( "mousedown", this._cancelEvent);
            jQueryImgDel.unbind( "click", imgDel._mouseClickHandler);
            imgDel._mouseClickHandler = null;
            jQueryImgDel.unbind( "mouseenter", this._hiliteHoverImage );
            jQueryImgDel.unbind( "mouseleave", this._unhiliteHoverImage );
        }
        
        el.IconsData = null;
    },
    
    _hiliteHoverImage : function(ev){
        if( this.tagName == "IMG" )
        {
            jQuery( this ).css( "opacity", 1 );
        }
    },
    
    _unhiliteHoverImage : function(ev){
        if( this.tagName == "IMG" )
        {
            jQuery( this ).css( "opacity", 0.5 );
        }
    },
    
    _cancelEvent : function( ev ){
        var jQueryEvent = jQuery.event.fix( ev );
		jQueryEvent.preventDefault();
		jQueryEvent.stopPropagation();
    },
    
    _onDeleteApp : function( el, ev ){
        if( confirm( this._confirmDeleteMesage ) )
    	{
    	    this.postback( ["delete",this._getAppID(el) ] );
        }
        this._cancelEvent( ev );        
    },
    
    _onEditApp : function( el, ev ){
        var appData = this._getAppData( el );
    	if(null != appData)
    	{    	
    	    this._startEditApp( el, appData.Title );
            
    	    this._hideAppIcons( el );
    	    this._cancelEvent( ev );
    	}
    },
    
    _startEditApp : function( el, sDefText ){
        this._isEditing = true;
        var textEl = document.createElement( "input" );    	
		textEl.type = "text";
		textEl.id = "event_edit";
		textEl.value = sDefText;
		textEl.onblur = Function.createDelegate( this, this._textEditBlur);		
		textEl.style.borderWidth = "0px";
		textEl.style.backgroundColor = "transparent";
		textEl.style.padding = "0px";		
        var bEditNewApp = (el ==this.btnAddEvent);
		var elA = bEditNewApp ? this.btnAddEventContent : el.getElementsByTagName("A")[0];
		var parEl = elA.parentNode;
		var jQueryParEl = jQuery(parEl);
		var sTextAlign = jQueryParEl.css("text-align");		
		if( ( sTextAlign == "center" )||
		    ( sTextAlign == "right" ) )
		{
		    if( !bEditNewApp )
		    {
		        textEl.style.textAlign = sTextAlign;
            }		        
		    parEl.style.textAlign = "left";
		}
		textEl.style.position = "absolute";
		textEl.style.width = jQueryParEl.innerWidth() + "px";
		textEl.style.height = jQueryParEl.innerHeight() + "px";
		elA.style.visibility = "hidden";		
		parEl.insertBefore( textEl, elA );
		var jQueryText = jQuery(textEl);
		textEl._onKeyPressHandler = this.createDelegate( this._textEditKeyPress);
		jQueryText.bind( "keypress", textEl._onKeyPressHandler);
		
		this.editData = {Editing : true, TextBox : textEl, Content : elA, Element : el, EditNewApp : bEditNewApp };
		
		jQueryText.bind( "mousedown", this._cancelEvent);
		jQueryText.bind( "click", this._cancelEvent);
    	
    	try
		{
		    textEl.select();
        }
        catch(e){}
    },
    
    _getAppData : function(el){
        var res = null;
        var appID = this._getAppID( el );
        appID = parseInt( appID, 10 );
        var itemData = this.get_items()[ appID ];
        if( null != itemData )
        {        
    	    var sTitle = itemData.Title;
    	    var editDisabled =  itemData.EditDisabled == "true";
    	    var deleteDisabled =  itemData.DeleteDisabled == "true";                
    	    res = {ID : appID, Title : sTitle, EditDisabled : editDisabled, DeleteDisabled : deleteDisabled };
    	}
    	return res;
    },
    
    _isItemDeleteEnabled : function(el){
        var appData = this._getAppData(el);
        return (null != appData) && this.allowDeleteItem && !appData.DeleteDisabled;
    },    
    _isItemTitleEditEnabled : function(el){
        return this.allowEditItemTitle && !this._isAppDataEditDisabled(el);
    },
    _isItemResizeEnabled : function(el){
        return this.allowResizeItem && !this._isAppDataEditDisabled(el);
    },
    _isItemDragEnabled : function(el){
        return this.allowDragItem && !this._isAppDataEditDisabled(el);
    },
    _isAppDataEditDisabled : function(el){
        var appData = this._getAppData(el);
        return (null == appData) || appData.EditDisabled;
    },
    
    _onAfterTextEdit : function(){
        var data = this.editData;
        var textEl = data.TextBox;
        var appCont = data.Content;
        var jQueryText = jQuery(textEl);        
        jQueryText.unbind( "mousedown", this._cancelEvent);
		jQueryText.unbind(textEl, "click", this._cancelEvent);
		textEl.onblur = null;
		jQueryText.unbind(textEl, "keypress", textEl._onKeyPressHandler);
		textEl._onKeyPressHandler = null;
		this._isEditing = false;
    },
    
    _textEditBlur : function(){
        this._applyTextEdit();
    },
    
    _textEditKeyPress : function(ev){        
        var bEnterKey = ev.keyCode == 13;
        var bEscKey = ev.keyCode == 27;
        if( bEnterKey || bEscKey )
        {
            if( bEscKey ){
                this._cancelTextEdit();                
            }
            else if( bEnterKey ){
                this._applyTextEdit();
            }
            window.focus();
            this._cancelEvent( ev );
        }
    },
    
    _cancelTextEdit : function(){
    	var data = this.editData;
        var textEl = data.TextBox;
        var appCont = data.Content;
        
        this._onAfterTextEdit();
        
        var parEl = textEl.parentNode;
        var textAlign = textEl.style.textAlign;
        if( textAlign )
        {
            parEl.style.textalign = "";
            if( jQuery(parEl).css("text-align")!=textAlign )
            {
                parEl.style.textAlign = textAlign;
            }
        }
        this.editData = null;
        
    	parEl.removeChild( textEl );
        appCont.style.visibility = "";
        
        if( data.EditNewApp )
        {
            this._hideAddEventButton();
        }
    },  
    
    _applyTextEdit : function( ev ){
        var data = this.editData;
        var textEl = data.TextBox;
        var appCont = data.Content;
        var appData = this._getAppData(data.Element);
        
        var sNewVal = textEl.value;
        
        if( ( !data.EditNewApp && ( sNewVal == appData.Title ) )||( "" == sNewVal ))
        {
            this._cancelTextEdit( ev );
        }
        else
        {
            //this._onAfterTextEdit(ev);            
            if( data.EditNewApp )
            {                
                var data = this.addAppointmentData;
                this._cancelTextEdit( ev );
                if(data)
                {
                    var date = data.Date;                
                    var bAllDay = data.AllDay;
                    //var propNames = [ "type", "year", "month", "date", "hour", "minute", "allday", "title"];
    		        var propVals = [ "add", date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), bAllDay ? 1 : 0, sNewVal];
                    this.postback( propVals );
                }
            }
            else
            {
                this._cancelTextEdit( ev );
                var sID = this._getAppID( data.Element )
                this.postback( [ "edit",sID,sNewVal ] );
            }
        }
    },
    
    _isAppEditing : function(el){
        var editData = this.editData;
        return editData && editData.Editing &&( editData.Element == el );
    },
    
    _showAppIcons : function( el ){
        if( this._isEventActionInProcess() )
    	    return false;
        if( this._isItemDeleteEnabled(el) || this._isItemTitleEditEnabled(el) )
        {
            var editData = this.editData;        
            this._ensureCreateIcons( el );        
            var cont = el.IconsData.Container;        
            var nLeft = jQuery( el ).offset().left + el.offsetWidth - cont.offsetWidth;
            cont.style.left = nLeft + "px";
            cont.style.visibility = "";
        }
    },
    
    _hideAppIcons : function( el ){
        if( el.IconsData )
        {
            var cont = el.IconsData.Container;
            cont.style.left = "-100px";
            cont.style.visibility = "hidden";
        }
    },
    
    _createBorderEl : function( bTop ){
    	var el = document.createElement( "div" );
    	var st = el.style;
    	st.height = "5px";
    	st.overflow="hidden";
    	st.backgroundColor="#FFFFFF";
    	st.padding = "0px";
    	st.borderWidth = "0px";
    	st.margin = "0px";
    	st.position = "absolute";
    	st.cursor = bTop ? "n-resize" : "s-resize";
    	jQuery( el ).css( "opacity", 0 );
    	el.isBorder = true;
    	el.direction = bTop ? "top" : "bottom";
    	
    	return el;
    },
    
    _removeOverlapingElement : function(){
        if( null != this._overlapedElement )
        {
            this._overlapedElement.parentNode.removeChild( this._overlapedElement );
            this._overlapedElement = null;
        }
    },
    
    _ensureCreateOverlapingElement : function(){
        if( null == this._overlapedElement )
        {
            this._overlapedElement = this._createOverlapingElement();
        }
        return this._overlapedElement;
    },
    
    _createOverlapingElement : function()
	{
	    var overDiv = document.createElement( "div" );
	    var oOverElStl = overDiv.style;
	    
	    if( jQuery.browser.mozilla || jQuery.browser.msie )
	    {
	        oOverElStl.backgroundColor = "#FFFFFF";
	        jQuery( overDiv ).css( "opacity", 0.01 );
	    }
	    else
	    {
	        oOverElStl.backgroundColor = "Transparent";
	    }
        oOverElStl.zIndex = 301;
        oOverElStl.fontSize = "1px";
        oOverElStl.overflow = "hidden";
        oOverElStl.position = "absolute";
        
        var doc = document.documentElement
        var body = document.body;        
		oOverElStl.top = (doc && doc.scrollTop || body && body.scrollTop || 0) + "px";
		oOverElStl.left = (doc && doc.scrollLeft || body && body.scrollLeft || 0) + "px";
		oOverElStl.width = (doc && doc.clientWidth || body && body.clientWidth || 0) + "px";
		oOverElStl.height = (doc && doc.clientHeight || body && body.clientHeight || window.innerHeight || 0) + "px";
		
		overDiv.innerHTML = "&nbsp";
		document.body.appendChild( overDiv );
        
        return overDiv;
	},
	
	_onAppMouseOver : function( el, ev ){
	    this._showAppIcons( el );
	},
	
	_onAppMouseOut : function( el, ev ){
	    this._hideAppIcons( el );
	},
    
    _isEventActionInProcess : function(){
        return this._isEditing || this._isDragging || this._isResizing;
    },
    
    /////////////////////////////////////////////////////////////////////////////
    //// Dragging events
    
    _onAppMouseDown : function( el, ev ){
        if( this._isItemDragEnabled(el) )
        {
		    var dragEl = this._getAppDragEl( el );		
		    window.AB_MoveManager.RegisterToMove( 
				dragEl, dragEl, 0,
				this.createDelegate( this._startDragging, [el]),
				this.createDelegate( this._doDragging, [el]),
				this.createDelegate( this._endDragging, [el]),
			    ev,
				this.createDelegate( this._endDragging, [el] ) );
        }
    },
    
    _startDragging : function( el, ev, el1 ){
        if( this._isEventActionInProcess() )
    	    return false;
    	this._hideAppIcons(el);
    	this._dropEl = window.AB_MoveManager.CreateMoveEffectEl( 3, el );
    	this._dropEl.style.visibility= "hidden";
    	this._dropEl.style.position= "absolute";
    	this._dropEl.style.top= "-100px";
    	this._dropEl.style.left= "-100px";
    	this._dropEl.style.zIndex = 200;
    	document.body.appendChild( this._dropEl );

    	var offset = jQuery( el ).offset();
    	this._movingOffset = { top : ev.pageY - offset.top, left : ev.pageX - offset.left };        
    	this._isDragging = true;
    	return true;
    },

    _doDragging : function( el, ev, el1, moveEl ){  
        var oRootTbl = this._getRootTable();
    	var rootOffset = jQuery( oRootTbl ).offset();
    	var eventOffset = {top : ev.pageY, left : ev.pageX };
    	var bOverDateContent = this._isOverTableDateContent( rootOffset, eventOffset );
    	var bOverAllDayContent = this._isOverAllDayEvents( rootOffset, eventOffset );
    	
    	var bRes = false;    	
    	if( bOverDateContent || bOverAllDayContent )
    	{    	    
    		if( !moveEl._inited )
    		{    		    
    			moveEl.style.width = el.offsetWidth + "px";
		    	moveEl.style.height = el.offsetHeight + "px";
		    	moveEl.style.cursor = "move";
		    	if( this._isAppAllDay( el ) )
                {
                    var sCssClass = this.isMonthView() ? el.parentNode.className : el.className;
                    jQuery( moveEl ).addClass( sCssClass );
                }
    			moveEl._inited = true;
    		}
    		var offsetWaste = this._getWasteOffset();
    		var nOffsetTop = 0;
    		if( bOverAllDayContent )
    		{
    		    nOffsetTop = ev.pageY;
    		}
    		else
    		{
    		    nOffsetTop = Math.max( ev.pageY - this._movingOffset.top, rootOffset.top + offsetWaste.top );
    		}
	    	var newOffset = { 
	    	    top : nOffsetTop,
                left : Math.max( ev.pageX, rootOffset.left + offsetWaste.left ) };
    		moveEl.style.top = Math.min( Math.max( ev.pageY - this._movingOffset.top, rootOffset.top + offsetWaste.top ), rootOffset.top + oRootTbl.offsetHeight - el.offsetHeight ) + "px";
    		moveEl.style.left = Math.min( Math.max( ev.pageX - this._movingOffset.left, rootOffset.left + offsetWaste.left ), rootOffset.left + oRootTbl.offsetWidth - el.offsetWidth ) + "px";
    		moveEl.style.visibility = "";
    		    		
    		var date = this._getDateByOffset( newOffset, true, rootOffset );
    		if( null != date )
    		{   
    		    var dateSize = this._getDateCellData( date, bOverAllDayContent, newOffset, rootOffset, offsetWaste );
    		    var nHeight = ( !this.isMonthView() && !bOverAllDayContent )?
    		        el.offsetHeight : dateSize.Height;
    		    this._dropEl.style.top = dateSize.Top + "px";
    		    this._dropEl.style.left = dateSize.Left + "px";
        		    		
    		    this._dropEl.style.width = dateSize.Width - 2 + "px";
    		    this._dropEl.style.height = nHeight - 2 + "px";
    		    this._dropEl.style.visibility= "";
        		
    		    this._dropEl.date = date;
    		    this._ensureCreateOverlapingElement().style.cursor = "move";
        		
    		    bRes = true;
            }
            else
            {
                bRes = false;
            }
    	}
    	if( !bRes )
    	{
    		moveEl.style.visibility = "hidden";
    		this._dropEl.style.visibility= "hidden"
    		this._dropEl.date = null;
    		this._ensureCreateOverlapingElement().style.cursor = "not-allowed";    		
    	}
    	this._dragAllDay = bOverAllDayContent;
    },
    
    _getDaysDelta : function( dt1, dt2 ){
        var nDays = 0;
        var dt2 = new Date( dt1.getFullYear(), dt2.getMonth(), dt2.getDate() );
        if( dt1 < dt2 ){
            while( dt2.getMonth() != dt1.getMonth() ){
                nDays += dt2.getDate();
                dt2.setDate( 0 );
            }
            nDays += dt2.getDate() - dt1.getDate();
        }
        return nDays;
    },

	_endDragging : function( el, ev, el1, moveEl, bCancel ){    	
    	var date = this._dropEl.date;
		if( !bCancel &&( date != null ))
    	{
    		var sID = this._getAppID(el);    		
 //   		var propNames = [ "type", "id", "year", "month", "date", "hour", "minute", "timeslot", "allday", "month view" ];
    		var propVals = [ "drag", sID, date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), this._slotsPerHour, this._dragAllDay ? 1 : 0, this.isMonthView() ? 1 : 0 ];    		
    		this.postback( propVals );
    	}
    	this._isDragging = false;
		window.AB_MoveManager.UnRegister( el );
		document.body.removeChild( this._dropEl );
		this._dropEl = null;
		this._removeOverlapingElement();		
    },
    
    /////////////////////////////////////////////////////////////////////////////
    //// Resizing events
    
    _onAppBorderMouseDown : function( el, border, ev ){
        if( this._isItemResizeEnabled(el) )
        {
		    window.AB_MoveManager.RegisterToMove( 
				el, el, 3,
				this.createDelegate( this._startResizing, [border]),
				this.createDelegate( this._doResizing, [border]),
				this.createDelegate( this._endResizing, [border]),
			    ev,
				this.createDelegate( this._endResizing, [border]) );
        }
		ev.preventDefault();
		ev.stopPropagation();
	},
    
    _startResizing : function( ev, el ){
	    if( this._isEventActionInProcess() )
    	    return false;
    	this._isResizing = true;
    	return true;
    },

    _doResizing : function( border, ev, el, moveEl ){	    
    	var oRootTbl = this._getRootTable();
    	var rootOffset = jQuery( oRootTbl ).offset();
		var eventOffset = {top : ev.pageY, left : ev.pageX }
    	if( this._isOverTableDateContent( rootOffset, eventOffset, oRootTbl ) )
    	{
    		if( !moveEl._inited )
    		{
		    	moveEl.style.cursor = ( border.direction == "top" ) ? "n-resize" : "s-resize";
    			moveEl._inited = true;
    		}

	    	var offsetWaste = this._getWasteOffset();
	    	var appOffset = jQuery( el ).offset();
	    	var dateEvent = this._getDateByOffset( eventOffset, false, rootOffset );
	    	var dateApp = this._getDateByOffset( appOffset, false, rootOffset );
	    	var dateAppEnd = this._getDateByOffset( { top : appOffset.top + el.offsetHeight - 2, left : appOffset.left }, false, rootOffset );
	    	
	    	var nColumnIdx = this._getDaysDelta( this.get_firstDate(), dateApp );
    		var nLeft = 0;
    		var nWidth = 0;
    		if( this.isDayView() )
    		{
    			nLeft = rootOffset.left + offsetWaste.left;
    			nWidth = oRootTbl.offsetWidth - offsetWaste.left;
    		}
    		else if( this.isWeekView() )
    		{
    			nLeft = rootOffset.left + offsetWaste.left;
    			var row = oRootTbl.rows[0];
    			for( var i = 0; i < nColumnIdx; ++i )
    			{
    				nLeft += row.cells[ i + 2 ].offsetWidth;
    			}
    			nWidth = row.cells[ nColumnIdx + 2 ].offsetWidth
    		}

			var nTop = 0;
			var nHeight = 0;
			if( border.direction == "top" )
			{
				nTop = rootOffset.top;	    	
				var nAppEndRowIdx = ( dateAppEnd.getHours() - this._startHour )*this._slotsPerHour + parseInt((dateAppEnd.getMinutes()*this._slotsPerHour)/60,10) + this._getHeaderRowsCount();
				var nEventRowIdx = ( dateEvent.getHours() - this._startHour )*this._slotsPerHour + parseInt((dateEvent.getMinutes()*this._slotsPerHour)/60,10) + this._getHeaderRowsCount();
				
				var nRowIdx = Math.min( nAppEndRowIdx, nEventRowIdx );
				for( var i =0; i < nRowIdx; ++i )
				{
					nTop += oRootTbl .rows[i].offsetHeight;
				}
				nHeight = appOffset.top - nTop + el.offsetHeight;
			}
			else
			{
				nTop = appOffset.top;
				
				var nAppStartRowIdx = ( dateApp.getHours() - this._startHour )*this._slotsPerHour + parseInt((dateApp.getMinutes()*this._slotsPerHour)/60,10) + this._getHeaderRowsCount();
				var nEventRowIdx = ( dateEvent.getHours() - this._startHour )*this._slotsPerHour + parseInt((dateEvent.getMinutes()*this._slotsPerHour)/60,10) + this._getHeaderRowsCount();
				var nRowIdx = Math.max( nEventRowIdx + 1, nAppStartRowIdx + 1 );
				for( var i = nAppStartRowIdx; i < nRowIdx; ++i )
				{
					nHeight += oRootTbl .rows[i].offsetHeight;
				}
			}
			
    		moveEl.style.top = nTop + "px";
    		moveEl.style.left = nLeft + "px";
    		moveEl.style.width = nWidth - 2 + "px";
    		moveEl.style.height = nHeight - 2 + "px";
			this.date = dateEvent;			
			this._ensureCreateOverlapingElement().style.cursor = ( border.direction == "top" ) ? "n-resize" : "s-resize";;
			
    	}
    	else
    	{
    		moveEl.style.visibility = "hidden";
    		this.date = null;
    		this._ensureCreateOverlapingElement().style.cursor = "not-allowed";
    	}
    },

	_endResizing : function( border, ev, el, moveEl, bCancel ){
    	var date = this.date;
		if( !bCancel &&( date != null ))
    	{
    		var sID = this._getAppID(el);
 //   		var propNames = [ "type", "id", "direction","month", "date", "hour", "minute", "timeslot" ];
    		var propVals = [ "resize", sID, border.direction, date.getHours(), date.getMinutes(), this._slotsPerHour ];
    		this.postback( propVals );
    	}
    	
    	this._isResizing = false;
		window.AB_MoveManager.UnRegister( el );		
		this._removeOverlapingElement();		
    },
    
    /////////////////////////////////////////////////////////////////////////////
    //// Implementation
    
    _isRecurrenceItem : function( el ){
        var id = this._getAppID( el );
        return parseInt( id, 10 ).toString() != id;
    },
    
    _getAppID :function( el ){
    	var sID = "";
   		var hRefEl = null;
   		if( this._isAppAllDay( el ) )
   		{
   		    var tables = this._getAllDayAppContent( el ).getElementsByTagName("TABLE");
   		    el = tables[tables.length - 1];
   		}
   		if( this.isMonthView() )
   		{
   		    hRefEl = el.getElementsByTagName("A")[0];
   		}
   		else
   		{
   		    if( el.tagName == "TABLE" )
   		    {
   			    hRefEl = el.rows[0].cells[0];
   		    }
   		    else
   		    {
   			    hRefEl = el;
   		    }
        }
   		
   		var sHref = jQuery( hRefEl ).attr( "href" );
   		if( sHref )
   		{
   		    var nIdx = sHref.indexOf( "?" );
   		    if( -1 != nIdx )
   		    {
   			    var sQueryStrings = sHref.substring( nIdx + 1, sHref.length );
   			    if( sQueryStrings )
   			    {
   				    var arrQueries = sQueryStrings.split("&");
   				    for( var i = 0; i < arrQueries.length; ++i )
   				    {
   					    var sQuery = arrQueries[i];
   					    var args = sQuery.split("=");
   					    if( args[0].toLowerCase() == "id" )
   					    {
   						    sID = args[1];
   						    break;
   					    }
   				    }
   			    }
   		    }
        }
   		return sID;
    }

}
ArtfulBits.CalendarPro.CalendarProWebPart.registerClass('ArtfulBits.CalendarPro.CalendarProWebPart', Sys.UI.Control);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();