/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"



// INCLUDE ---------------------------------------------------------------

#include <svx/svditer.hxx>
#include <svx/svdocapt.hxx>
#include <svx/svdpagv.hxx>
#include <sfx2/dispatch.hxx>
#include <editeng/outliner.hxx>

#include "fusel.hxx"
#include "tabvwsh.hxx"
#include "document.hxx"
#include "detfunc.hxx"
#include "futext.hxx"
#include "sc.hrc"
#include "attrib.hxx"
#include "scitems.hxx"
#include "userdat.hxx"
#include "drwlayer.hxx"
#include "docsh.hxx"
#include "drawview.hxx"
#include <svx/sdrhittesthelper.hxx>

// -----------------------------------------------------------------------

inline long Diff( const Point& rP1, const Point& rP2 )
{
	long nX = rP1.X() - rP2.X();
	if (nX<0) nX = -nX;
	long nY = rP1.Y() - rP2.Y();
	if (nY<0) nY = -nY;
	return nX+nY;
}

sal_Bool FuSelection::TestDetective( SdrPageView* pPV, const Point& rPos )
{
	if (!pPV)
		return sal_False;

	sal_Bool bFound = sal_False;
	SdrObjListIter aIter( *pPV->GetObjList(), IM_FLAT );
	SdrObject* pObject = aIter.Next();
	while (pObject && !bFound)
	{
		if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
		{
			sal_uInt16 nHitLog = (sal_uInt16) pWindow->PixelToLogic(
								Size(pView->GetHitTolerancePixel(),0)).Width();
			if (SdrObjectPrimitiveHit(*pObject, rPos, nHitLog, *pPV, 0, false))
			{
				ScViewData* pViewData = pViewShell->GetViewData();
				ScSplitPos ePos = pViewShell->FindWindow( pWindow );
				Point aLineStart = pObject->GetPoint(0);
				Point aLineEnd   = pObject->GetPoint(1);
				Point aPixel = pWindow->LogicToPixel( aLineStart );
				SCsCOL nStartCol;
				SCsROW nStartRow;
				pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), ePos, nStartCol, nStartRow );
				aPixel = pWindow->LogicToPixel( aLineEnd );
				SCsCOL nEndCol;
				SCsROW nEndRow;
				pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), ePos, nEndCol, nEndRow );
				SCsCOL nCurX = (SCsCOL) pViewData->GetCurX();
				SCsROW nCurY = (SCsROW) pViewData->GetCurY();
				sal_Bool bStart = ( Diff( rPos,aLineStart ) > Diff( rPos,aLineEnd ) );
				if ( nCurX == nStartCol && nCurY == nStartRow )
					bStart = sal_False;
				else if ( nCurX == nEndCol && nCurY == nEndRow )
					bStart = sal_True;

				SCsCOL nDifX;
				SCsROW nDifY;
				if ( bStart )
				{
					nDifX = nStartCol - nCurX;
					nDifY = nStartRow - nCurY;
				}
				else
				{
					nDifX = nEndCol - nCurX;
					nDifY = nEndRow - nCurY;
				}
				pViewShell->MoveCursorRel( nDifX, nDifY, SC_FOLLOW_JUMP, sal_False );

				bFound = sal_True;
			}
		}

		pObject = aIter.Next();
	}
	return bFound;
}

bool FuSelection::IsNoteCaptionMarked() const
{
    if( pView )
    {
        const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
        if( rMarkList.GetMarkCount() == 1 )
        {
            SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
            return ScDrawLayer::IsNoteCaption( pObj );
        }
    }
    return false;
}

bool FuSelection::IsNoteCaptionClicked( const Point& rPos ) const
{
    SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
    if( pPageView )
    {
        const ScViewData& rViewData = *pViewShell->GetViewData();
        ScDocument& rDoc = *rViewData.GetDocument();
        SCTAB nTab = rViewData.GetTabNo();
        ScDocShell* pDocSh = rViewData.GetDocShell();
        bool bProtectDoc =  rDoc.IsTabProtected( nTab ) || (pDocSh && pDocSh->IsReadOnly());

        // search the last object (on top) in the object list
        SdrObjListIter aIter( *pPageView->GetObjList(), IM_DEEPNOGROUPS, sal_True );
        for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
        {
            if( pObj->GetLogicRect().IsInside( rPos ) )
            {
                if( const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab ) )
                {
                    const ScAddress& rNotePos = pCaptData->maStart;
                    // skip caption objects of notes in protected cells
                    const ScProtectionAttr* pProtAttr =  static_cast< const ScProtectionAttr* >( rDoc.GetAttr( rNotePos.Col(), rNotePos.Row(), nTab, ATTR_PROTECTION ) );
                    bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell();
                    if( !bProtectAttr || !bProtectDoc )
                        return true;
                }
            }
        }
    }
    return false;
}

void FuSelection::ActivateNoteHandles(SdrObject* pObject)
{
    if( pView && ScDrawLayer::IsNoteCaption( pObject ) )
    {
        // Leave the internal layer unlocked - relock in ScDrawView::MarkListHasChanged()
        pView->UnlockInternalLayer();
        pView->MarkObj( pObject, pView->GetSdrPageView() );
    }
}

//==================================================================




