/**************************************************************
 * 
 * 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 <osl/mutex.hxx>
#include <xmloff/xmltoken.hxx>
#include <rtl/uuid.h>
#include <rtl/memory.h>
#include <xmloff/attrlist.hxx>
#include "MutableAttrList.hxx"

using ::rtl::OUString;

using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;

SvXMLAttributeList *XMLMutableAttributeList::GetMutableAttrList()
{
	if( !m_pMutableAttrList )
	{
		m_pMutableAttrList = new SvXMLAttributeList( m_xAttrList );
		m_xAttrList = m_pMutableAttrList;
	}

	return m_pMutableAttrList;
}

XMLMutableAttributeList::XMLMutableAttributeList() :
	m_pMutableAttrList( new SvXMLAttributeList )
{
	m_xAttrList = m_pMutableAttrList;
}

XMLMutableAttributeList::XMLMutableAttributeList( const Reference< 
		XAttributeList> & rAttrList, sal_Bool bClone ) :
	m_xAttrList( rAttrList.is() ? rAttrList : new SvXMLAttributeList ),
	m_pMutableAttrList( 0 )
{
	if( bClone )
		GetMutableAttrList();
}


XMLMutableAttributeList::~XMLMutableAttributeList()
{
	m_xAttrList = 0;
}


// XUnoTunnel & co
const Sequence< sal_Int8 > & XMLMutableAttributeList::getUnoTunnelId() throw()
{
	static Sequence< sal_Int8 > * pSeq = 0;
	if( !pSeq )
	{
		Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
		if( !pSeq )
		{
			static Sequence< sal_Int8 > aSeq( 16 );
			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
			pSeq = &aSeq;
		}
	}
	return *pSeq;
}

// XUnoTunnel
sal_Int64 SAL_CALL XMLMutableAttributeList::getSomething( 
		const Sequence< sal_Int8 >& rId )
	throw( RuntimeException )
{
	if( rId.getLength() == 16 && 
		0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
								rId.getConstArray(), 16 ) )
	{
		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
	}
	return 0;
}

sal_Int16 SAL_CALL XMLMutableAttributeList::getLength(void) 
		throw( RuntimeException )
{
	return m_xAttrList->getLength();
}


OUString SAL_CALL XMLMutableAttributeList::getNameByIndex(sal_Int16 i) 
		throw( RuntimeException )
{
	return m_xAttrList->getNameByIndex( i );
}


OUString SAL_CALL XMLMutableAttributeList::getTypeByIndex(sal_Int16 i) 
		throw( RuntimeException )
{
	return m_xAttrList->getTypeByIndex( i );
}

OUString SAL_CALL  XMLMutableAttributeList::getValueByIndex(sal_Int16 i)
	throw( RuntimeException )
{
	return m_xAttrList->getValueByIndex( i );
}

OUString SAL_CALL XMLMutableAttributeList::getTypeByName( 
		const OUString& rName ) 
		throw( RuntimeException )
{
	return m_xAttrList->getTypeByName( rName );
}

OUString SAL_CALL XMLMutableAttributeList::getValueByName(
		const OUString& rName) 
		throw( RuntimeException )
{
	return m_xAttrList->getValueByName( rName );
}


Reference< XCloneable > XMLMutableAttributeList::createClone() 
		throw( RuntimeException )
{
	// A cloned list will be a read only list!
	Reference< XCloneable >  r = new SvXMLAttributeList( m_xAttrList );
	return r;
}

void XMLMutableAttributeList::SetValueByIndex( sal_Int16 i, 
											   const ::rtl::OUString& rValue )
{
	GetMutableAttrList()->SetValueByIndex( i, rValue );
}

void XMLMutableAttributeList::AddAttribute( const OUString &rName , 
											const OUString &rValue )
{
	GetMutableAttrList()->AddAttribute( rName, rValue );
}

void XMLMutableAttributeList::RemoveAttributeByIndex( sal_Int16 i )
{
	GetMutableAttrList()->RemoveAttributeByIndex( i );
}

void XMLMutableAttributeList::RenameAttributeByIndex( sal_Int16 i,
												  	const OUString& rNewName )
{
	GetMutableAttrList()->RenameAttributeByIndex( i, rNewName );
}

void XMLMutableAttributeList::AppendAttributeList( 
		const Reference< ::com::sun::star::xml::sax::XAttributeList >& r )
{
	GetMutableAttrList()->AppendAttributeList( r );
}

sal_Int16 XMLMutableAttributeList::GetIndexByName( const OUString& rName ) const
{
	sal_Int16 nIndex = -1;
	if( m_pMutableAttrList )
	{
		nIndex = m_pMutableAttrList->GetIndexByName( rName );
	}
	else
	{
		sal_Int16 nCount = m_xAttrList->getLength();
		for( sal_Int16 i=0; nIndex==-1 && i<nCount ; ++i )
		{
			if( m_xAttrList->getNameByIndex(i) == rName )
				nIndex = i;
		}
	}
	return nIndex;
}
