/**************************************************************
 *
 * 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_xmloff.hxx"
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/document/XLinkAuthorizer.hpp>
#include "FillStyleContext.hxx"
#include <xmloff/xmlimp.hxx>
#include "xmloff/GradientStyle.hxx"
#include "xmloff/HatchStyle.hxx"
#include "xmloff/ImageStyle.hxx"
#include "TransGradientStyle.hxx"
#include "xmloff/MarkerStyle.hxx"
#include "xmloff/DashStyle.hxx"
#include <xmloff/families.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/XMLBase64ImportContext.hxx>

using namespace ::com::sun::star;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLGradientStyleContext, SvXMLStyleContext );

XMLGradientStyleContext::XMLGradientStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										      const OUString& rLName,
											  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// set Family
//	SetFamily( XML_STYLE_FAMILY_FILLSTYLE_GRADIENT_ID );

	// start import
	XMLGradientStyleImport aGradientStyle( GetImport() );
	aGradientStyle.importXML( xAttrList, maAny, maStrName );
}

XMLGradientStyleContext::~XMLGradientStyleContext()
{
}

void XMLGradientStyleContext::EndElement()
{
	uno::Reference< container::XNameContainer > xGradient( GetImport().GetGradientHelper() );

	try
	{
		if(xGradient.is())
		{
			if( xGradient->hasByName( maStrName ) )
			{
				xGradient->replaceByName( maStrName, maAny );
			}
			else
			{
				xGradient->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLGradientStyleContext::IsTransient() const
{
	return sal_True;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLHatchStyleContext, SvXMLStyleContext );

XMLHatchStyleContext::XMLHatchStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										      const OUString& rLName,
											  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// start import
	XMLHatchStyleImport aHatchStyle( GetImport() );
	aHatchStyle.importXML( xAttrList, maAny, maStrName );
}

XMLHatchStyleContext::~XMLHatchStyleContext()
{
}

void XMLHatchStyleContext::EndElement()
{
	uno::Reference< container::XNameContainer > xHatch( GetImport().GetHatchHelper() );

	try
	{
		if(xHatch.is())
		{
			if( xHatch->hasByName( maStrName ) )
			{
				xHatch->replaceByName( maStrName, maAny );
			}
			else
			{
				xHatch->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLHatchStyleContext::IsTransient() const
{
	return sal_True;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLBitmapStyleContext, SvXMLStyleContext );

XMLBitmapStyleContext::XMLBitmapStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										      const OUString& rLName,
											  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// start import
	XMLImageStyle aBitmapStyle;
	aBitmapStyle.importXML( xAttrList, maAny, maStrName, rImport );
}

XMLBitmapStyleContext::~XMLBitmapStyleContext()
{
}

SvXMLImportContext* XMLBitmapStyleContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = 0;
	if( (XML_NAMESPACE_OFFICE == nPrefix) && xmloff::token::IsXMLToken( rLocalName, xmloff::token::XML_BINARY_DATA ) )
	{
		OUString sURL;
		maAny >>= sURL;
		if( !sURL.getLength() && !mxBase64Stream.is() )
		{
			mxBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
			if( mxBase64Stream.is() )
				pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													mxBase64Stream );
		}
	}
	if( !pContext )
	{
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
	}

	return pContext;
}

void XMLBitmapStyleContext::EndElement()
{
	OUString sURL;
	maAny >>= sURL;

	if( !sURL.getLength() && mxBase64Stream.is() )
	{
		sURL = GetImport().ResolveGraphicObjectURLFromBase64( mxBase64Stream );
		mxBase64Stream = 0;
		maAny <<= sURL;
	}

	uno::Reference< document::XLinkAuthorizer > xLinkAuthorizer( GetImport().GetModel(), uno::UNO_QUERY);
	if ( xLinkAuthorizer.is() ) {
		if ( !xLinkAuthorizer->authorizeLinks( sURL ) ) {
			return;
		}
	}

	uno::Reference< container::XNameContainer > xBitmap( GetImport().GetBitmapHelper() );

	try
	{
		if(xBitmap.is())
		{
			if( xBitmap->hasByName( maStrName ) )
			{
				xBitmap->replaceByName( maStrName, maAny );
			}
			else
			{
				xBitmap->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLBitmapStyleContext::IsTransient() const
{
	return sal_True;
}


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLTransGradientStyleContext, SvXMLStyleContext );

XMLTransGradientStyleContext::XMLTransGradientStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										      const OUString& rLName,
											  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// start import
	XMLTransGradientStyleImport aTransGradientStyle( GetImport() );
	aTransGradientStyle.importXML( xAttrList, maAny, maStrName );
}

XMLTransGradientStyleContext::~XMLTransGradientStyleContext()
{
}

void XMLTransGradientStyleContext::EndElement()
{
	uno::Reference< container::XNameContainer > xTransGradient( GetImport().GetTransGradientHelper() );

	try
	{
		if(xTransGradient.is())
		{
			if( xTransGradient->hasByName( maStrName ) )
			{
				xTransGradient->replaceByName( maStrName, maAny );
			}
			else
			{
				xTransGradient->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLTransGradientStyleContext::IsTransient() const
{
	return sal_True;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLMarkerStyleContext, SvXMLStyleContext );

XMLMarkerStyleContext::XMLMarkerStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										      const OUString& rLName,
											  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// start import
	XMLMarkerStyleImport aMarkerStyle( GetImport() );
	aMarkerStyle.importXML( xAttrList, maAny, maStrName );
}

XMLMarkerStyleContext::~XMLMarkerStyleContext()
{
}

void XMLMarkerStyleContext::EndElement()
{
	uno::Reference< container::XNameContainer > xMarker( GetImport().GetMarkerHelper() );

	try
	{
		if(xMarker.is())
		{
			if( xMarker->hasByName( maStrName ) )
			{
				xMarker->replaceByName( maStrName, maAny );
			}
			else
			{
				xMarker->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLMarkerStyleContext::IsTransient() const
{
	return sal_True;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLDashStyleContext, SvXMLStyleContext );

XMLDashStyleContext::XMLDashStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
										  const OUString& rLName,
										  const uno::Reference< xml::sax::XAttributeList >& xAttrList)
:	SvXMLStyleContext(rImport, nPrfx, rLName, xAttrList)
{
	// start import
	XMLDashStyleImport aDashStyle( GetImport() );
	aDashStyle.importXML( xAttrList, maAny, maStrName );
}

XMLDashStyleContext::~XMLDashStyleContext()
{
}

void XMLDashStyleContext::EndElement()
{
	uno::Reference< container::XNameContainer > xDashes( GetImport().GetDashHelper() );

	try
	{
		if(xDashes.is())
		{
			if( xDashes->hasByName( maStrName ) )
			{
				xDashes->replaceByName( maStrName, maAny );
			}
			else
			{
				xDashes->insertByName( maStrName, maAny );
			}
		}
	}
	catch( container::ElementExistException& )
	{}
}

sal_Bool XMLDashStyleContext::IsTransient() const
{
	return sal_True;
}
