/**************************************************************
 *
 * 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_vcl.hxx"
#include <tools/stream.hxx>
#include <tools/vcompat.hxx>
#include <tools/debug.hxx>
#include <vcl/lineinfo.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dlinegeometry.hxx>
#include <numeric>

DBG_NAME( LineInfo )

// ----------------
// - ImplLineInfo -
// ----------------

ImplLineInfo::ImplLineInfo() :
    mnRefCount	( 1 ),
    meStyle		( LINE_SOLID ),
	mnWidth		( 0 ),
	mnDashCount	( 0 ),
	mnDashLen	( 0 ),
	mnDotCount	( 0 ),
	mnDotLen	( 0 ),
	mnDistance	( 0 ),
    meLineJoin  ( basegfx::B2DLINEJOIN_ROUND ),
    meLineCap   ( com::sun::star::drawing::LineCap_BUTT )
{
}

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

ImplLineInfo::ImplLineInfo( const ImplLineInfo& rImplLineInfo ) :
	mnRefCount	( 1 ),
    meStyle		( rImplLineInfo.meStyle ),
	mnWidth		( rImplLineInfo.mnWidth ),
	mnDashCount	( rImplLineInfo.mnDashCount	),
	mnDashLen	( rImplLineInfo.mnDashLen ),
	mnDotCount	( rImplLineInfo.mnDotCount ),
	mnDotLen	( rImplLineInfo.mnDotLen ),
	mnDistance	( rImplLineInfo.mnDistance ),
    meLineJoin  ( rImplLineInfo.meLineJoin ),
    meLineCap   ( rImplLineInfo.meLineCap )
{
}

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

inline bool ImplLineInfo::operator==( const ImplLineInfo& rB ) const
{
	return(meStyle == rB.meStyle
		&& mnWidth == rB.mnWidth
		&& mnDashCount == rB.mnDashCount
		&& mnDashLen == rB.mnDashLen
		&& mnDotCount == rB.mnDotCount
		&& mnDotLen == rB.mnDotLen
		&& mnDistance == rB.mnDistance
		&& meLineJoin == rB.meLineJoin
        && meLineCap == rB.meLineCap);
}

// ------------
// - LineInfo -
// ------------

LineInfo::LineInfo( LineStyle eStyle, long nWidth )
{
    DBG_CTOR( LineInfo, NULL );
    mpImplLineInfo = new ImplLineInfo;
    mpImplLineInfo->meStyle = eStyle;
    mpImplLineInfo->mnWidth = nWidth;
}

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

LineInfo::LineInfo( const LineInfo& rLineInfo )
{
    DBG_CTOR( LineInfo, NULL );
    DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );
    mpImplLineInfo = rLineInfo.mpImplLineInfo;
    mpImplLineInfo->mnRefCount++;
}

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

LineInfo::~LineInfo()
{
    DBG_DTOR( LineInfo, NULL );
    if( !( --mpImplLineInfo->mnRefCount ) )
        delete mpImplLineInfo;
}

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

LineInfo& LineInfo::operator=( const LineInfo& rLineInfo )
{
    DBG_CHKTHIS( LineInfo, NULL );
    DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );

    rLineInfo.mpImplLineInfo->mnRefCount++;

    if( !( --mpImplLineInfo->mnRefCount ) )
        delete mpImplLineInfo;

	mpImplLineInfo = rLineInfo.mpImplLineInfo;
    return *this;
}

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

sal_Bool LineInfo::operator==( const LineInfo& rLineInfo ) const
{
    DBG_CHKTHIS( LineInfo, NULL );
    DBG_CHKOBJ( &rLineInfo, LineInfo, NULL );

    return( mpImplLineInfo == rLineInfo.mpImplLineInfo ||
           *mpImplLineInfo == *rLineInfo.mpImplLineInfo );
}

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

void LineInfo::ImplMakeUnique()
{
    if( mpImplLineInfo->mnRefCount != 1 )
	{
		if( mpImplLineInfo->mnRefCount )
			mpImplLineInfo->mnRefCount--;

        mpImplLineInfo = new ImplLineInfo( *mpImplLineInfo );
	}
}

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

void LineInfo::SetStyle( LineStyle eStyle )
{
    DBG_CHKTHIS( LineInfo, NULL );
    ImplMakeUnique();
    mpImplLineInfo->meStyle = eStyle;
}

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

void LineInfo::SetWidth( long nWidth )
{
    DBG_CHKTHIS( LineInfo, NULL );
    ImplMakeUnique();
    mpImplLineInfo->mnWidth = nWidth;
}

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

void LineInfo::SetDashCount( sal_uInt16 nDashCount )
{
	DBG_CHKTHIS( LineInfo, NULL );
	ImplMakeUnique();
	mpImplLineInfo->mnDashCount = nDashCount;
}

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

void LineInfo::SetDashLen( long nDashLen )
{
	DBG_CHKTHIS( LineInfo, NULL );
	ImplMakeUnique();
	mpImplLineInfo->mnDashLen = nDashLen;
}

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

void LineInfo::SetDotCount( sal_uInt16 nDotCount )
{
	DBG_CHKTHIS( LineInfo, NULL );
	ImplMakeUnique();
	mpImplLineInfo->mnDotCount = nDotCount;
}

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

void LineInfo::SetDotLen( long nDotLen )
{
	DBG_CHKTHIS( LineInfo, NULL );
	ImplMakeUnique();
	mpImplLineInfo->mnDotLen = nDotLen;
}

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

void LineInfo::SetDistance( long nDistance )
{
	DBG_CHKTHIS( LineInfo, NULL );
	ImplMakeUnique();
	mpImplLineInfo->mnDistance = nDistance;
}

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

void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin)
{
	DBG_CHKTHIS( LineInfo, NULL );

    if(eLineJoin != mpImplLineInfo->meLineJoin)
    {
    	ImplMakeUnique();
        mpImplLineInfo->meLineJoin = eLineJoin;
    }
}

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

void LineInfo::SetLineCap(com::sun::star::drawing::LineCap eLineCap)
{
    DBG_CHKTHIS( LineInfo, NULL );

    if(eLineCap != mpImplLineInfo->meLineCap)
    {
        ImplMakeUnique();
        mpImplLineInfo->meLineCap = eLineCap;
    }
}

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

sal_Bool LineInfo::IsDefault() const
{
    return( !mpImplLineInfo->mnWidth
        && ( LINE_SOLID == mpImplLineInfo->meStyle )
        && ( com::sun::star::drawing::LineCap_BUTT == mpImplLineInfo->meLineCap));
}

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

SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
{
    VersionCompat	aCompat( rIStm, STREAM_READ );
    sal_uInt16			nTmp16;

    rIStm >> nTmp16; rImplLineInfo.meStyle = (LineStyle) nTmp16;
    rIStm >> rImplLineInfo.mnWidth;

	if( aCompat.GetVersion() >= 2 )
	{
		// version 2
		rIStm >> rImplLineInfo.mnDashCount >> rImplLineInfo.mnDashLen;
		rIStm >> rImplLineInfo.mnDotCount >> rImplLineInfo.mnDotLen;
		rIStm >> rImplLineInfo.mnDistance;
	}

	if( aCompat.GetVersion() >= 3 )
	{
		// version 3
        rIStm >> nTmp16; rImplLineInfo.meLineJoin = (basegfx::B2DLineJoin) nTmp16;
    }

    if( aCompat.GetVersion() >= 4 )
    {
        // version 4
        rIStm >> nTmp16; rImplLineInfo.meLineCap = (com::sun::star::drawing::LineCap) nTmp16;
    }

    return rIStm;
}

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

SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo )
{
    VersionCompat aCompat( rOStm, STREAM_WRITE, 4 );

    // version 1
	rOStm << (sal_uInt16) rImplLineInfo.meStyle << rImplLineInfo.mnWidth;

	// since version2
	rOStm << rImplLineInfo.mnDashCount << rImplLineInfo.mnDashLen;
	rOStm << rImplLineInfo.mnDotCount << rImplLineInfo.mnDotLen;
	rOStm << rImplLineInfo.mnDistance;

	// since version3
	rOStm << (sal_uInt16) rImplLineInfo.meLineJoin;

    // since version4
    rOStm << (sal_uInt16) rImplLineInfo.meLineCap;

    return rOStm;
}

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

SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo )
{
    rLineInfo.ImplMakeUnique();
    return( rIStm >> *rLineInfo.mpImplLineInfo );
}

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

SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo )
{
    return( rOStm << *rLineInfo.mpImplLineInfo );
}

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

bool LineInfo::isDashDotOrFatLineUsed() const
{
	return (LINE_DASH == GetStyle() || GetWidth() > 1);
}

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

void LineInfo::applyToB2DPolyPolygon(
	basegfx::B2DPolyPolygon& io_rLinePolyPolygon,
	basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const
{
	o_rFillPolyPolygon.clear();

	if(io_rLinePolyPolygon.count())
	{
		if(LINE_DASH == GetStyle())
		{
			::std::vector< double > fDotDashArray;
			const double fDashLen(GetDashLen());
			const double fDotLen(GetDotLen());
			const double fDistance(GetDistance());

			for(sal_uInt16 a(0); a < GetDashCount(); a++)
			{
				fDotDashArray.push_back(fDashLen);
				fDotDashArray.push_back(fDistance);
			}

			for(sal_uInt16 b(0); b < GetDotCount(); b++)
			{
				fDotDashArray.push_back(fDotLen);
				fDotDashArray.push_back(fDistance);
			}

			const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));

			if(fAccumulated > 0.0)
			{
				basegfx::B2DPolyPolygon aResult;

				for(sal_uInt32 c(0); c < io_rLinePolyPolygon.count(); c++)
				{
					basegfx::B2DPolyPolygon aLineTraget;
					basegfx::tools::applyLineDashing(
						io_rLinePolyPolygon.getB2DPolygon(c),
						fDotDashArray,
						&aLineTraget);
					aResult.append(aLineTraget);
				}

				io_rLinePolyPolygon = aResult;
			}
		}

		if(GetWidth() > 1 && io_rLinePolyPolygon.count())
		{
			const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);

			for(sal_uInt32 a(0); a < io_rLinePolyPolygon.count(); a++)
			{
				o_rFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
					io_rLinePolyPolygon.getB2DPolygon(a),
					fHalfLineWidth,
					GetLineJoin(),
                    GetLineCap()));
			}

			io_rLinePolyPolygon.clear();
		}
	}
}

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