/**************************************************************
 *
 * 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/xml/AttributeData.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>

#include <xmloff/xmlcnimp.hxx>
#include "xmloff/unoatrcn.hxx"

using namespace rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::xml;

typedef ::rtl::OUString *OUStringPtr;
SV_DECL_PTRARR_DEL( SvXMLAttrContainerData_Impl, OUStringPtr, 5, 5 )
SV_IMPL_PTRARR( SvXMLAttrContainerData_Impl, OUStringPtr )


SvXMLAttrContainerData::SvXMLAttrContainerData(
							const SvXMLAttrContainerData& rImpl ) :
	aNamespaceMap( rImpl.aNamespaceMap ),
	pLNames( new SvXMLAttrContainerData_Impl ),
	pValues( new SvXMLAttrContainerData_Impl )
{
	sal_uInt16 nCount = rImpl.pLNames->Count();
	for( sal_uInt16 i=0; i<nCount; i++ )
	{
		aPrefixPoss.Insert( rImpl.aPrefixPoss[i], i );
		pLNames->Insert( new OUString( *(*rImpl.pLNames)[i] ), i );
		pValues->Insert( new OUString( *(*rImpl.pValues)[i] ), i );
	}
}

SvXMLAttrContainerData::SvXMLAttrContainerData() :
	pLNames( new SvXMLAttrContainerData_Impl ),
	pValues( new SvXMLAttrContainerData_Impl )
{
}

SvXMLAttrContainerData::~SvXMLAttrContainerData()
{
	delete pLNames;
	delete pValues;
}

int SvXMLAttrContainerData::operator ==(
						const SvXMLAttrContainerData& rCmp ) const
{
	sal_Bool bRet = pLNames->Count() == rCmp.pLNames->Count() &&
				aNamespaceMap == rCmp.aNamespaceMap;
	if( bRet )
	{
		sal_uInt16 nCount = pLNames->Count();
		sal_uInt16 i;
		for( i=0; bRet && i < nCount; i++ )
			bRet = aPrefixPoss[i] == rCmp.aPrefixPoss[i];

		if( bRet )
		{
			for( i=0; bRet && i < nCount; i++ )
				bRet = *(*pLNames)[i] == *(*rCmp.pLNames)[i] &&
					   *(*pValues)[i] == *(*rCmp.pValues)[i];
		}
	}

	return (int)bRet;
}

sal_Bool SvXMLAttrContainerData::AddAttr( const OUString& rLName,
									   	   const OUString& rValue )
{
	aPrefixPoss.Insert( USHRT_MAX, aPrefixPoss.Count() );
	pLNames->Insert( new OUString(rLName), pLNames->Count() );
	pValues->Insert( new OUString(rValue), pValues->Count() );

	return sal_True;
}

sal_Bool SvXMLAttrContainerData::AddAttr( const OUString& rPrefix,
									   	   const OUString& rNamespace,
									       const OUString& rLName,
									 	   const OUString& rValue )
{
	sal_uInt16 nPos = aNamespaceMap.Add( rPrefix, rNamespace );
	aPrefixPoss.Insert( nPos, aPrefixPoss.Count() );
	pLNames->Insert( new OUString(rLName), pLNames->Count() );
	pValues->Insert( new OUString(rValue), pValues->Count() );

	return sal_True;
}

sal_Bool SvXMLAttrContainerData::AddAttr( const OUString& rPrefix,
									       const OUString& rLName,
									 	   const OUString& rValue )
{
	sal_uInt16 nPos = aNamespaceMap.GetIndexByPrefix( rPrefix );
	if( USHRT_MAX == nPos )
		return sal_False;

	aPrefixPoss.Insert( nPos, aPrefixPoss.Count() );
	pLNames->Insert( new OUString(rLName), pLNames->Count() );
	pValues->Insert( new OUString(rValue), pValues->Count() );

	return sal_True;
}

sal_Bool SvXMLAttrContainerData::SetAt( sal_uInt16 i,
			const rtl::OUString& rLName, const rtl::OUString& rValue )
{
	if( i >= GetAttrCount() )
		return sal_False;

	*(*pLNames)[i] = rLName;
	*(*pValues)[i] = rValue;
	aPrefixPoss[i] = USHRT_MAX;

	return sal_True;
}

sal_Bool SvXMLAttrContainerData::SetAt( sal_uInt16 i,
			const rtl::OUString& rPrefix, const rtl::OUString& rNamespace,
			const rtl::OUString& rLName, const rtl::OUString& rValue )
{
	if( i >= GetAttrCount() )
		return sal_False;

	sal_uInt16 nPos = aNamespaceMap.Add( rPrefix, rNamespace );
	if( USHRT_MAX == nPos )
		return sal_False;

	*(*pLNames)[i] = rLName;
	*(*pValues)[i] = rValue;
	aPrefixPoss[i] = nPos;

	return sal_True;
}

sal_Bool SvXMLAttrContainerData::SetAt( sal_uInt16 i,
			const rtl::OUString& rPrefix,
			const rtl::OUString& rLName,
			const rtl::OUString& rValue )
{
	if( i >= GetAttrCount() )
		return sal_False;

	sal_uInt16 nPos = aNamespaceMap.GetIndexByPrefix( rPrefix );
	if( USHRT_MAX == nPos )
		return sal_False;

	*(*pLNames)[i] = rLName;
	*(*pValues)[i] = rValue;
	aPrefixPoss[i] = nPos;

	return sal_True;
}

void SvXMLAttrContainerData::Remove( sal_uInt16 i )
{
	if( i < GetAttrCount() )
	{
		delete (*pLNames)[i];
		pLNames->Remove( i );
		delete (*pValues)[i];
		pValues->Remove( i );
		aPrefixPoss.Remove( i );
	}
	else
	{
		DBG_ERROR( "illegal index" );
	}
}

sal_uInt16 SvXMLAttrContainerData::GetAttrCount() const
{
	return pLNames->Count();
}

const ::rtl::OUString& SvXMLAttrContainerData::GetAttrLName(sal_uInt16 i) const
{
	OSL_ENSURE( i < pLNames->Count(), "SvXMLAttrContainerData::GetLName: illegal index" );
	return *(*pLNames)[i];
}

const ::rtl::OUString& SvXMLAttrContainerData::GetAttrValue(sal_uInt16 i) const
{
	OSL_ENSURE( i < pValues->Count(), "SvXMLAttrContainerData::GetValue: illegal index" );
	return *(*pValues)[i];
}
