/**************************************************************
 *
 * 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 <tools/debug.hxx>
#include <com/sun/star/io/XOutputStream.hpp>
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmluconv.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/XMLBase64ImportContext.hxx>
#include "XMLBackgroundImageContext.hxx"

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::io;
using namespace ::xmloff::token;

enum SvXMLTokenMapAttrs
{
	XML_TOK_BGIMG_HREF,
	XML_TOK_BGIMG_TYPE,
	XML_TOK_BGIMG_ACTUATE,
	XML_TOK_BGIMG_SHOW,
	XML_TOK_BGIMG_POSITION,
	XML_TOK_BGIMG_REPEAT,
	XML_TOK_BGIMG_FILTER,
    XML_TOK_BGIMG_OPACITY,
	XML_TOK_NGIMG_END=XML_TOK_UNKNOWN
};
const SvXMLTokenMapEntry* lcl_getBGImgAttributesAttrTokenMap()
{
    static __FAR_DATA SvXMLTokenMapEntry aBGImgAttributesAttrTokenMap[] =
    {
	    { XML_NAMESPACE_XLINK, XML_HREF, 		XML_TOK_BGIMG_HREF		},
	    { XML_NAMESPACE_XLINK, XML_TYPE, 		XML_TOK_BGIMG_TYPE		},
	    { XML_NAMESPACE_XLINK, XML_ACTUATE,	    XML_TOK_BGIMG_ACTUATE	},
	    { XML_NAMESPACE_XLINK, XML_SHOW, 		XML_TOK_BGIMG_SHOW 		},
	    { XML_NAMESPACE_STYLE, XML_POSITION, 	XML_TOK_BGIMG_POSITION	},
	    { XML_NAMESPACE_STYLE, XML_REPEAT, 	    XML_TOK_BGIMG_REPEAT	},
	    { XML_NAMESPACE_STYLE, XML_FILTER_NAME, XML_TOK_BGIMG_FILTER	},
        { XML_NAMESPACE_DRAW,  XML_OPACITY,		XML_TOK_BGIMG_OPACITY	},
	    XML_TOKEN_MAP_END
    };
    return aBGImgAttributesAttrTokenMap;
}



SvXMLEnumMapEntry psXML_BrushHoriPos[] =
{
	{ XML_LEFT, 		GraphicLocation_LEFT_MIDDLE	},
	{ XML_RIGHT,		GraphicLocation_RIGHT_MIDDLE	},
	{ XML_TOKEN_INVALID,					0			}
};

SvXMLEnumMapEntry psXML_BrushVertPos[] =
{
	{ XML_TOP,			GraphicLocation_MIDDLE_TOP	},
	{ XML_BOTTOM,		GraphicLocation_MIDDLE_BOTTOM	},
	{ XML_TOKEN_INVALID,					0			}
};

void lcl_xmlbic_MergeHoriPos( GraphicLocation& ePos,
								   GraphicLocation eHori )
{
	DBG_ASSERT( GraphicLocation_LEFT_MIDDLE==eHori ||
				GraphicLocation_MIDDLE_MIDDLE==eHori ||
				GraphicLocation_RIGHT_MIDDLE==eHori,
				"lcl_xmlbic_MergeHoriPos: vertical pos must be middle" );

	switch( ePos )
	{
	case GraphicLocation_LEFT_TOP:
	case GraphicLocation_MIDDLE_TOP:
	case GraphicLocation_RIGHT_TOP:
		ePos = GraphicLocation_LEFT_MIDDLE==eHori
				? GraphicLocation_LEFT_TOP
				: (GraphicLocation_MIDDLE_MIDDLE==eHori
						? GraphicLocation_MIDDLE_TOP
						: GraphicLocation_RIGHT_TOP);
		break;

	case GraphicLocation_LEFT_MIDDLE:
	case GraphicLocation_MIDDLE_MIDDLE:
	case GraphicLocation_RIGHT_MIDDLE:
		ePos = eHori;
		break;

	case GraphicLocation_LEFT_BOTTOM:
	case GraphicLocation_MIDDLE_BOTTOM:
	case GraphicLocation_RIGHT_BOTTOM:
		ePos = GraphicLocation_LEFT_MIDDLE==eHori
				? GraphicLocation_LEFT_BOTTOM
				: (GraphicLocation_MIDDLE_MIDDLE==eHori
						? GraphicLocation_MIDDLE_BOTTOM
						: GraphicLocation_RIGHT_BOTTOM);
		break;
	default:
		break;
	}
}

void lcl_xmlbic_MergeVertPos( GraphicLocation& ePos,
							  	   			  GraphicLocation eVert )
{
	DBG_ASSERT( GraphicLocation_MIDDLE_TOP==eVert ||
				GraphicLocation_MIDDLE_MIDDLE==eVert ||
				GraphicLocation_MIDDLE_BOTTOM==eVert,
				"lcl_xmlbic_MergeVertPos: horizontal pos must be middle" );

	switch( ePos )
	{
	case GraphicLocation_LEFT_TOP:
	case GraphicLocation_LEFT_MIDDLE:
	case GraphicLocation_LEFT_BOTTOM:
		ePos = GraphicLocation_MIDDLE_TOP==eVert
				? GraphicLocation_LEFT_TOP
				: (GraphicLocation_MIDDLE_MIDDLE==eVert
						? GraphicLocation_LEFT_MIDDLE
						: GraphicLocation_LEFT_BOTTOM);
		ePos = eVert;
		break;

	case GraphicLocation_MIDDLE_TOP:
	case GraphicLocation_MIDDLE_MIDDLE:
	case GraphicLocation_MIDDLE_BOTTOM:
		ePos = eVert;
		break;

	case GraphicLocation_RIGHT_TOP:
	case GraphicLocation_RIGHT_MIDDLE:
	case GraphicLocation_RIGHT_BOTTOM:
		ePos = GraphicLocation_MIDDLE_TOP==eVert
				? GraphicLocation_RIGHT_TOP
				: (GraphicLocation_MIDDLE_MIDDLE==eVert
						? GraphicLocation_RIGHT_MIDDLE
						: GraphicLocation_RIGHT_BOTTOM);
		break;
	default:
		break;
	}
}

TYPEINIT1( XMLBackgroundImageContext, XMLElementPropertyContext );

void XMLBackgroundImageContext::ProcessAttrs(
		const Reference< xml::sax::XAttributeList >& xAttrList )
{
	SvXMLTokenMap aTokenMap( lcl_getBGImgAttributesAttrTokenMap() );

	ePos = GraphicLocation_NONE;

	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		switch( aTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_BGIMG_HREF:
			sURL = rValue;
			if( GraphicLocation_NONE == ePos )
				ePos = GraphicLocation_TILED;
			break;
		case XML_TOK_BGIMG_TYPE:
		case XML_TOK_BGIMG_ACTUATE:
		case XML_TOK_BGIMG_SHOW:
			break;
		case XML_TOK_BGIMG_POSITION:
			{
				GraphicLocation eNewPos = GraphicLocation_NONE, eTmp;
				sal_uInt16 nTmp;
				SvXMLTokenEnumerator aTokenEnum( rValue );
				OUString aToken;
				sal_Bool bHori = sal_False, bVert = sal_False;
				sal_Bool bOK = sal_True;
				while( bOK && aTokenEnum.getNextToken( aToken ) )
				{
					if( bHori && bVert )
					{
						bOK = sal_False;
					}
					else if( -1 != aToken.indexOf( sal_Unicode('%') ) )
					{
						sal_Int32 nPrc = 50;
						if( SvXMLUnitConverter::convertPercent( nPrc, aToken ) )
						{
							if( !bHori )
							{
								eNewPos = nPrc < 25
									? GraphicLocation_LEFT_TOP
									: (nPrc < 75 ? GraphicLocation_MIDDLE_MIDDLE
												: GraphicLocation_RIGHT_BOTTOM);
								bHori = sal_True;
							}
							else
							{
								eTmp = nPrc < 25
									? GraphicLocation_LEFT_TOP
									: (nPrc < 75 ? GraphicLocation_LEFT_MIDDLE
											     : GraphicLocation_LEFT_BOTTOM);
								lcl_xmlbic_MergeVertPos( eNewPos, eTmp );
								bVert = sal_True;
							}
						}
						else
						{
							// wrong percentage
							bOK = sal_False;
						}
					}
					else if( IsXMLToken( aToken, XML_CENTER ) )
					{
						if( bHori )
							lcl_xmlbic_MergeVertPos( eNewPos,
										  GraphicLocation_MIDDLE_MIDDLE );
						else if ( bVert )
							lcl_xmlbic_MergeHoriPos( eNewPos,
										  GraphicLocation_MIDDLE_MIDDLE );
						else
							eNewPos = GraphicLocation_MIDDLE_MIDDLE;
					}
					else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
														 psXML_BrushHoriPos ) )
					{
						if( bVert )
							lcl_xmlbic_MergeHoriPos( eNewPos,
										(GraphicLocation)nTmp );
						else if( !bHori )
							eNewPos = (GraphicLocation)nTmp;
						else
							bOK = sal_False;
						bHori = sal_True;
					}
					else if( SvXMLUnitConverter::convertEnum( nTmp, aToken,
														 psXML_BrushVertPos ) )
					{
						if( bHori )
							lcl_xmlbic_MergeVertPos( eNewPos,
											(GraphicLocation)nTmp );
						else if( !bVert )
							eNewPos = (GraphicLocation)nTmp;
						else
							bOK = sal_False;
						bVert = sal_True;
					}
					else
					{
						bOK = sal_False;
					}
				}

				bOK &= GraphicLocation_NONE != eNewPos;
				if( bOK )
					ePos = eNewPos;
			}
			break;
		case XML_TOK_BGIMG_REPEAT:
			{
				sal_uInt16 nPos = GraphicLocation_NONE;
                static SvXMLEnumMapEntry psXML_BrushRepeat[] =
                {
	                { XML_BACKGROUND_REPEAT,		GraphicLocation_TILED	},
	                { XML_BACKGROUND_NO_REPEAT, 	GraphicLocation_MIDDLE_MIDDLE		},
	                { XML_BACKGROUND_STRETCH,		GraphicLocation_AREA	},
	                { XML_TOKEN_INVALID,			0			}
                };
				if( SvXMLUnitConverter::convertEnum( nPos, rValue,
												psXML_BrushRepeat ) )
				{
					if( GraphicLocation_MIDDLE_MIDDLE != nPos ||
						GraphicLocation_NONE == ePos ||
						GraphicLocation_AREA == ePos ||
						GraphicLocation_TILED == ePos )
						ePos = (GraphicLocation)nPos;
				}
			}
			break;
		case XML_TOK_BGIMG_FILTER:
			sFilter = rValue;
			break;
        case XML_TOK_BGIMG_OPACITY:
            {
                sal_Int32 nTmp;
                // convert from percent and clip
                if( SvXMLUnitConverter::convertPercent( nTmp, rValue ) )
                {
                    if( (nTmp >= 0) && (nTmp <= 100) )
                        nTransparency = static_cast<sal_Int8>( 100-nTmp );
                }
            }
            break;
		}
	}

}

XMLBackgroundImageContext::XMLBackgroundImageContext(
		SvXMLImport& rImport, sal_uInt16 nPrfx,
		const OUString& rLName,
		const Reference< xml::sax::XAttributeList > & xAttrList,
		const XMLPropertyState& rProp,
		sal_Int32 nPosIdx,
		sal_Int32 nFilterIdx,
        sal_Int32 nTransparencyIdx,
		::std::vector< XMLPropertyState > &rProps ) :
	XMLElementPropertyContext( rImport, nPrfx, rLName, rProp, rProps ),
	aPosProp( nPosIdx ),
	aFilterProp( nFilterIdx ),
    aTransparencyProp( nTransparencyIdx ),
    nTransparency( 0 )
{
	ProcessAttrs( xAttrList );
}

XMLBackgroundImageContext::~XMLBackgroundImageContext()
{
}

SvXMLImportContext *XMLBackgroundImageContext::CreateChildContext(
		sal_uInt16 nPrefix, const OUString& rLocalName,
		const Reference< xml::sax::XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = NULL;
	if( (XML_NAMESPACE_OFFICE == nPrefix) &&
		xmloff::token::IsXMLToken( rLocalName,
										xmloff::token::XML_BINARY_DATA ) )
	{
		if( !sURL.getLength() && !xBase64Stream.is() )
		{
			xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
			if( xBase64Stream.is() )
				pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													xBase64Stream );
		}
	}
	if( !pContext )
	{
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
	}

	return pContext;
}

void XMLBackgroundImageContext::EndElement()
{
	if( sURL.getLength() )
	{
		sURL = GetImport().ResolveGraphicObjectURL( sURL, sal_False );
	}
	else if( xBase64Stream.is() )
	{
		sURL = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream );
		xBase64Stream = 0;
	}

	if( !sURL.getLength() )
		ePos = GraphicLocation_NONE;
	else if( GraphicLocation_NONE == ePos )
		ePos = GraphicLocation_TILED;

	aProp.maValue <<= sURL;
	aPosProp.maValue <<= ePos;
	aFilterProp.maValue <<= sFilter;
    aTransparencyProp.maValue <<= nTransparency;

	SetInsert( sal_True );
	XMLElementPropertyContext::EndElement();

	if( -1 != aPosProp.mnIndex )
		rProperties.push_back( aPosProp );
	if( -1 != aFilterProp.mnIndex )
		rProperties.push_back( aFilterProp );
	if( -1 != aTransparencyProp.mnIndex )
		rProperties.push_back( aTransparencyProp );
}
