/**************************************************************
 *
 * 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_cppcanvas.hxx"

#include <rtl/math.hxx>

#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/PathJoinType.hpp>
#include <com/sun/star/rendering/PathCapType.hpp>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tools/canvastools.hxx>

#include "implpolypolygon.hxx"
#include "tools.hxx"


using namespace ::com::sun::star;


namespace cppcanvas
{
    namespace internal
    {
        ImplPolyPolygon::ImplPolyPolygon( const CanvasSharedPtr& rParentCanvas,
                                          const uno::Reference< rendering::XPolyPolygon2D >& rPolyPoly ) :
            CanvasGraphicHelper( rParentCanvas ),
            mxPolyPoly( rPolyPoly ),
            maStrokeAttributes(1.0,
                               10.0,
                               uno::Sequence< double >(),
                               uno::Sequence< double >(),
                               rendering::PathCapType::ROUND,
                               rendering::PathCapType::ROUND,
                               rendering::PathJoinType::ROUND ),
            maFillColor(),
            maStrokeColor(),
            mbFillColorSet( false ),
            mbStrokeColorSet( false )
        {
            OSL_ENSURE( mxPolyPoly.is(), "PolyPolygonImpl::PolyPolygonImpl: no valid polygon" );
        }

        ImplPolyPolygon::~ImplPolyPolygon()
        {
        }

        void ImplPolyPolygon::addPolygon( const ::basegfx::B2DPolygon& rPoly )
        {
            OSL_ENSURE( mxPolyPoly.is(),
                        "ImplPolyPolygon::addPolygon(): Invalid polygon" );

            if( !mxPolyPoly.is() )
                return;

            uno::Reference< rendering::XGraphicDevice > xDevice( getGraphicDevice() );

            OSL_ENSURE( xDevice.is(),
                        "ImplPolyPolygon::addPolygon(): Invalid graphic device" );

            if( !xDevice.is() )
                return;

            mxPolyPoly->addPolyPolygon( geometry::RealPoint2D(0.0, 0.0),
                                        ::basegfx::unotools::xPolyPolygonFromB2DPolygon(
                                            xDevice,
                                            rPoly) );
        }

        void ImplPolyPolygon::addPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly )
        {
            OSL_ENSURE( mxPolyPoly.is(),
                        "ImplPolyPolygon::addPolyPolygon(): Invalid polygon" );

            if( !mxPolyPoly.is() )
                return;

            uno::Reference< rendering::XGraphicDevice > xDevice( getGraphicDevice() );

            OSL_ENSURE( xDevice.is(),
                        "ImplPolyPolygon::addPolyPolygon(): Invalid graphic device" );

            if( !xDevice.is() )
                return;

            mxPolyPoly->addPolyPolygon( geometry::RealPoint2D(0.0, 0.0),
                                        ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
                                            xDevice,
                                            rPoly) );
        }

        void ImplPolyPolygon::setRGBAFillColor( Color::IntSRGBA aColor )
        {
            maFillColor = tools::intSRGBAToDoubleSequence( getGraphicDevice(),
                                                           aColor );
            mbFillColorSet = true;
        }

        void ImplPolyPolygon::setRGBALineColor( Color::IntSRGBA aColor )
        {
            maStrokeColor = tools::intSRGBAToDoubleSequence( getGraphicDevice(),
                                                             aColor );
            mbStrokeColorSet = true;
        }

        Color::IntSRGBA ImplPolyPolygon::getRGBAFillColor() const
        {
            return tools::doubleSequenceToIntSRGBA( getGraphicDevice(),
                                                    maFillColor );
        }

        Color::IntSRGBA ImplPolyPolygon::getRGBALineColor() const
        {
            return tools::doubleSequenceToIntSRGBA( getGraphicDevice(),
                                                    maStrokeColor );
        }

        void ImplPolyPolygon::setStrokeWidth( const double& rStrokeWidth )
        {
            maStrokeAttributes.StrokeWidth = rStrokeWidth;
        }

        double ImplPolyPolygon::getStrokeWidth() const
        {
            return maStrokeAttributes.StrokeWidth;
        }

        bool ImplPolyPolygon::draw() const
        {
            CanvasSharedPtr pCanvas( getCanvas() );

            OSL_ENSURE( pCanvas.get() != NULL &&
                        pCanvas->getUNOCanvas().is(),
                        "ImplBitmap::draw: invalid canvas" );

            if( pCanvas.get() == NULL ||
                !pCanvas->getUNOCanvas().is() )
                return false;

            if( mbFillColorSet )
            {
                rendering::RenderState aLocalState( getRenderState() );
                aLocalState.DeviceColor = maFillColor;

                pCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
                                                          pCanvas->getViewState(),
                                                          aLocalState );
            }

            if( mbStrokeColorSet )
            {
                rendering::RenderState aLocalState( getRenderState() );
                aLocalState.DeviceColor = maStrokeColor;

                if( ::rtl::math::approxEqual(maStrokeAttributes.StrokeWidth, 1.0) )
                    pCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
                                                              pCanvas->getViewState(),
                                                              aLocalState );
                else
                    pCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
                                                                pCanvas->getViewState(),
                                                                aLocalState,
                                                                maStrokeAttributes );
            }

            return true;
        }

        uno::Reference< rendering::XPolyPolygon2D > ImplPolyPolygon::getUNOPolyPolygon() const
        {
            return mxPolyPoly;
        }

    }
}
