/*
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 * Copyright (C) 2003-2007 Frederico Caldeira Knabben
 *
 * == BEGIN LICENSE ==
 *
 * Licensed under the terms of any of the following licenses at your
 * choice:
 *
 *  - GNU General Public License Version 2 or later (the "GPL")
 *    http://www.gnu.org/licenses/gpl.html
 *
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 *    http://www.gnu.org/licenses/lgpl.html
 *
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 *
 * == END LICENSE ==
 *
 * Manage table operations (IE specific).
 */

FCKTableHandler.GetSelectedCells = function()
{
	var aCells = new Array() ;

	if ( this._HasCellSelection() )
	{
		var minPos = FCKTools.GetWindowPosition( window, this._DragSelectBlock ) ;
		var offset = FCKTools.GetDocumentPosition( window, FCK.EditingArea.IFrame ) ;
		minPos.x += 100 - offset.x ;
		minPos.y += 100 - offset.y ;
		var maxPos = { 'x' : minPos.x + this._DragSelectBlock.offsetWidth - 200, 
			'y' : minPos.y + this._DragSelectBlock.offsetHeight - 200 } ;

		for ( var i = 0 ; i < this._SelectedTable.rows.length ; i++ )
		{
			var r = this._SelectedTable.rows[i] ;
			for ( var j = 0 ; j < r.cells.length ; j++ )
			{
				var cellPos = FCKTools.GetWindowPosition( FCK.EditorWindow, r.cells[j] ) ;
				/*
				FCKDebug.Output( cellPos.x + ":" + cellPos.y + ";" + minPos.x + ":" + minPos.y + ";"
						+ maxPos.x + ":" + maxPos.y ) ;
				*/
				if ( cellPos.x >= minPos.x && cellPos.y >= minPos.y 
						&& cellPos.x <= maxPos.x && cellPos.y <= maxPos.y )
					aCells.push( r.cells[j] ) ;
			}
		}
	}
	else
	{
		var oParent = FCKSelection.GetParentElement() ;
		if ( oParent && oParent.tagName.Equals( 'TD', 'TH' ) )
			aCells.push( oParent ) ;
	}

	return aCells ;
}

FCKTableHandler._DragSelectBlock = null ;

FCKTableHandler._SelectedTable = null ;

FCKTableHandler._AnchorCell = null ;

FCKTableHandler._CellSelectMode = false ;

FCKTableHandler.MouseMoveHandler = function( FCK, evt )
{
	if ( ! FCK.MouseDownFlag )
	{
		if ( FCKTableHandler._SelectedTable )
			FCKTableHandler._CancelCellSelectMode() ;
		return ;
	}

	var target = evt.srcElement || evt.target ;
	var mouse = { 'x' : evt.clientX, 'y' : evt.clientY } ;
	if ( target.ownerDocument != FCK.EditorDocument )
	{
		var offset = FCKTools.GetDocumentPosition( window, FCK.EditingArea.IFrame ) ;
		mouse.x -= offset.x ;
		mouse.y -= offset.y ;
	}

	if ( FCKTableHandler._CellSelectMode )
		FCKTableHandler._DragSelectHandler( FCK, target, mouse ) ;
	else
		FCKTableHandler._FindSelectHandler( FCK, target, mouse ) ;
}

FCKTableHandler.OuterMouseMoveHandler = function( evt )
{
	return FCKTableHandler.MouseMoveHandler( FCK, evt ) ;
}

FCKTableHandler.MouseUpHandler = function( evt )
{
	FCKTableHandler._CancelCellSelectMode() ;
	FCK.MouseDownFlag = false ;
}

FCKTableHandler.MouseDownHandler = function( evt )
{
	if ( evt.button == 1 && FCKTableHandler._CellSelectMode == false && FCKTableHandler._SelectedTable )
		FCKTableHandler._ClearCellSelectOverlay() ;
}

FCKTableHandler._HasCellSelection = function()
{
	return this._SelectedTable && this._DragSelectBlock && this._DragSelectBlock.style.display != 'none' ;
}

FCKTableHandler._CancelCellSelectMode = function()
{
	this._CellSelectMode = false ;
}

FCKTableHandler._ClearCellSelectOverlay = function()
{
	if ( this._DragSelectBlock )
		this._DragSelectBlock.style.display = 'none' ;
	this._SelectedTable = null ;
	this._AnchorCell = null ;
}

FCKTableHandler._FindSelectHandler = function( FCK, target, mouse )
{
	try
	{
		if ( ! target || target.nodeType != 1 )
			return ;
	}
	catch ( e )
	{
		return ;
	}

	var targetTag = target.tagName.toLowerCase() ;
	if ( targetTag == 'td' )
	{
		this._AnchorCell = target ;
		this._SelectedTable = FCKTools.GetElementAscensor( target, 'table' ) ;
		this._CellSelectMode = true ;
	}
}

FCKTableHandler._DragSelectHandler = function( FCK, target, mouse)
{
	// 1. find out the table cell on which the mouse cursor has rested on.
	var table = this._SelectedTable ;
	var tablePosition = FCKTools.GetWindowPosition( FCK.EditorWindow, table ) ;

	if ( mouse.x < tablePosition.x || mouse.y < tablePosition.y
			|| mouse.x > tablePosition.x + table.offsetWidth
			|| mouse.y > tablePosition.y + table.offsetHeight )
		return ;

	var cells = [] ;
	for ( var i = 0 ; i < table.rows.length ; i++ )
	{
		var r = table.rows[i] ;
		for ( var j = 0 ; j < r.cells.length ; j++ )
			cells.push( r.cells[j] ) ;
	}

	var boundingCell = null ;
	for ( var i = 0 ; i < cells.length ; i++ ) 
	{
		var pos = FCKTools.GetWindowPosition( FCK.EditorWindow, cells[i] ) ;
		if ( mouse.x >= pos.x && mouse.y >= pos.y && mouse.x <= pos.x + cells[i].offsetWidth
				&& mouse.y <= pos.y + cells[i].offsetHeight )
		{
			boundingCell = cells[i] ;
			break ;
		}
	}

	if ( boundingCell == null )
		return ;

	// 2. if mouse cursor is on a different cell compared to anchor cell, display the overlay select block.
	if ( boundingCell != this._AnchorCell )
	{
		if ( this._DragSelectBlock == null ) 
		{
			var overlay = document.createElement( 'div' ) ;
			overlay.style.position = 'absolute' ;
			overlay.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=10,enabled=true)' ;
			document.body.appendChild( overlay ) ;

			var filler = document.createElement( 'img' ) ;
			filler.border = 0 ;
			filler.src = FCKConfig.BasePath + 'images/spacer.gif' ;
			filler.style.position = 'absolute' ;
			overlay.appendChild( filler ) ;
			var visibleBlock = document.createElement( 'div' ) ;
			FCKTools.SetNodeStyles( visibleBlock, { 'position' : 'absolute', 'backgroundColor' : 'blue' } ) ;
			overlay.appendChild( visibleBlock ) ;
			this._DragSelectBlock = overlay ;

			FCKTools.AddEventListener( FCK.EditorDocument, "mouseup", this.MouseUpHandler ) ;
			FCKTools.AddEventListener( document, "mouseup", this.MouseUpHandler ) ;
			FCKTools.AddEventListener( document, "mousemove", this.OuterMouseMoveHandler ) ;
			FCKTools.AddEventListener( FCK.EditorDocument, "mousedown", this.MouseDownHandler ) ;
			FCKTools.AddEventListener( document, "mousedown", this.MouseDownHandler ) ;
			FCK.ContextMenu._InnerContextMenu.AttachToElement( overlay ) ;
		}

		this._DragSelectBlock.style.display = '' ;
		var r = FCK.EditorDocument.body.createControlRange() ;
		r.add( this._SelectedTable ) ;
		r.select() ;
	}

	// 3. if there is a select block, update its position and resize it.
	if ( ! this._HasCellSelection() )
		return ;
	this._FocusCell = boundingCell ;
	this._RefreshSelectionBlock( FCK ) ;
}

FCKTableHandler._RefreshSelectionBlock = function( FCK )
{
	var anchorPos = FCKTools.GetWindowPosition( FCK.EditorWindow, this._AnchorCell ) ;
	var focusPos = FCKTools.GetWindowPosition( FCK.EditorWindow, this._FocusCell ) ;
	var minPos = 
	{ 
		'x' : ( anchorPos.x < focusPos.x ? anchorPos.x : focusPos.x ), 
		'y' : ( anchorPos.y < focusPos.y ? anchorPos.y : focusPos.y ) 
	} ;
	var maxPos = 
	{
		'x' : ( anchorPos.x + this._AnchorCell.offsetWidth > focusPos.x + this._FocusCell.offsetWidth ? 
				anchorPos.x + this._AnchorCell.offsetWidth : focusPos.x + this._FocusCell.offsetWidth ), 
		'y' : ( anchorPos.y + this._AnchorCell.offsetHeight > focusPos.y + this._FocusCell.offsetHeight ? 
				anchorPos.y + this._AnchorCell.offsetHeight : focusPos.y + this._FocusCell.offsetHeight ) 
	} ;
	var offset = FCKTools.GetDocumentPosition( window, FCK.EditingArea.IFrame ) ;
	var overlayStyle = 
	{
		'left'	: ( minPos.x - 100 + offset.x ) + 'px',
		'top' 	: ( minPos.y - 100 + offset.y ) + 'px',
		'width'	: ( maxPos.x - minPos.x + 200 ) + 'px',
		'height': ( maxPos.y - minPos.y + 200 ) + 'px'
	} ;
	var imgStyle = 
	{
		'left'	: '0px',
		'top'	: '0px',
		'width'	: overlayStyle.width,
		'height': overlayStyle.height
	} ;
	var visibleBlockStyle = 
	{
		'left'	: '100px',
		'top'	: '100px',
		'width'	: ( maxPos.x - minPos.x ) + 'px',
		'height': ( maxPos.y - minPos.y ) + 'px'
	} ;
	FCKTools.SetNodeStyles( this._DragSelectBlock, overlayStyle ) ;
	FCKTools.SetNodeStyles( this._DragSelectBlock.getElementsByTagName( 'img' )[0], imgStyle ) ;
	FCKTools.SetNodeStyles( this._DragSelectBlock.getElementsByTagName( 'div' )[0], visibleBlockStyle ) ;
}

FCK.Events.AttachEvent( "OnMouseMove", FCKTableHandler.MouseMoveHandler ) ;
