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

#include <ctype.h>
#include <stdio.h>

#include <tools/debug.hxx>

#include <attrib.hxx>
#include <object.hxx>
#include <globals.hxx>
#include <database.hxx>

/******************** class SvClassElement *******************************/
SV_IMPL_PERSIST1( SvClassElement, SvPersistBase );

/*************************************************************************
|*    SvClassElement::SvClassElement()
|*
|*    Beschreibung
*************************************************************************/
SvClassElement::SvClassElement()
{
};

/*************************************************************************
|*    SvClassElement::Load()
|*
|*    Beschreibung
*************************************************************************/
void SvClassElement::Load( SvPersistStream & rStm )
{
    sal_uInt8 nMask;
    rStm >> nMask;
    if( nMask >= 0x08 )
    {
        rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
        DBG_ERROR( "wrong format" );
        return;
    }
    if( nMask & 0x01 ) rStm >> aAutomation;
    if( nMask & 0x02 ) rStm.ReadByteString( aPrefix );
    if( nMask & 0x04 )
	{
		SvMetaClass * p;
		rStm >> p;
    	xClass = p;
	}
}

/*************************************************************************
|*    SvClassElement::Save()
|*
|*    Beschreibung
*************************************************************************/
void SvClassElement::Save( SvPersistStream & rStm )
{
    // Maske erstellen
    sal_uInt8 nMask = 0;
    if( aAutomation.IsSet() ) 		nMask |= 0x1;
    if( aPrefix.Len() )		  		nMask |= 0x2;
    if( xClass.Is() )				nMask |= 0x4;

    // Daten schreiben
    rStm << nMask;
	if( nMask & 0x01 ) rStm << aAutomation;
    if( nMask & 0x02 ) rStm.WriteByteString( aPrefix );
    if( nMask & 0x04 ) rStm << xClass;
}

/****************** SvMetaClass ******************************************/
SV_IMPL_META_FACTORY1( SvMetaClass, SvMetaType );
/*************************************************************************
|*    SvMetaClass::SvMetaClass()
|*
|*    Beschreibung
*************************************************************************/
SvMetaClass::SvMetaClass()
	: aAutomation( sal_True, sal_False )
{
}

/*************************************************************************
|*    SvMetaClass::Load()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::Load( SvPersistStream & rStm )
{
    SvMetaType::Load( rStm );

    sal_uInt8 nMask;
    rStm >> nMask;
    if( nMask >= 0x20 )
    {
        rStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
        DBG_ERROR( "wrong format" );
        return;
    }
    if( nMask & 0x01 ) rStm >> aAttrList;
    if( nMask & 0x02 )
	{
		SvMetaClass * pSuper;
		 rStm >> pSuper;
    	aSuperClass = pSuper;
	}
    if( nMask & 0x04 ) rStm >> aClassList;
    if( nMask & 0x8 )
	{
		SvMetaClass * p;
		rStm >> p;
    	xAutomationInterface = p;
	}
	if( nMask & 0x10 ) rStm >> aAutomation;
}

/*************************************************************************
|*    SvMetaClass::Save()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::Save( SvPersistStream & rStm )
{
    SvMetaType::Save( rStm );

    // Maske erstellen
    sal_uInt8 nMask = 0;
    if( aAttrList.Count() ) 		nMask |= 0x1;
    if( aSuperClass.Is() )  		nMask |= 0x2;
    if( aClassList.Count() )		nMask |= 0x4;
    if( xAutomationInterface.Is() ) nMask |= 0x8;
	if( aAutomation.IsSet() )		nMask |= 0x10;

    // Daten schreiben
    rStm << nMask;
    if( nMask & 0x01 ) rStm << aAttrList;
    if( nMask & 0x02 ) rStm << aSuperClass;
    if( nMask & 0x04 ) rStm << aClassList;
    if( nMask & 0x08 ) rStm << xAutomationInterface;
	if( nMask & 0x10 ) rStm << aAutomation;
}

/*************************************************************************
|*    SvMetaClass::FillSbxObject()
|*
|*    Beschreibung
*************************************************************************/
/*
void SvMetaClass::FillSbxMemberObject( SvIdlDataBase & rBase,
										SbxObject * pObj,
										StringList & rSuperList,
										sal_Bool bVariable )
{
	// alle Attribute der Klasse schreiben
	sal_uLong n ;
	for( n = 0; n < aAttrList.Count(); n++ )
	{
		SvMetaAttribute * pAttr = aAttrList.GetObject( n );

		ByteString aMangleName = pAttr->GetMangleName( bVariable );
		ByteString * pS = SvIdlDataBase::FindName( aMangleName, rSuperList );

		if( !pS && pAttr->GetExport() )
		{
			// nicht doppelt
			if( bVariable && pAttr->IsVariable() )
			{
				rSuperList.Insert( new ByteString( aMangleName ), LIST_APPEND );
 				pAttr->FillSbxObject( rBase, pObj, bVariable );
			}
			else if( !bVariable && pAttr->IsMethod() )
			{
				rSuperList.Insert( new ByteString( aMangleName ), LIST_APPEND );
				pAttr->FillSbxObject( rBase, pObj, bVariable );
			}
		}
	}
	// alle Attribute der importierten Klassen schreiben
	for( n = 0; n < aClassList.Count(); n++ )
	{
		SvClassElement * pEle = aClassList.GetObject( n );
		SvMetaClass * pClass = pEle->GetClass();
		pClass->FillSbxMemberObject( rBase, pObj, rSuperList, bVariable );
	}
	// alle Attribute der Superklassen schreiben
    if( aSuperClass.Is() )
		aSuperClass->FillSbxMemberObject( rBase, pObj, rSuperList, bVariable );
}
*/
/*************************************************************************
|*    SvMetaClass::FillSbxObject()
|*
|*    Beschreibung
*************************************************************************/
/*
void SvMetaClass::FillSbxObject( SvIdlDataBase & rBase, SbxObject * pObj )
{
    StringList aSuperList;
    FillSbxMemberObject( rBase, pObj, aSuperList, sal_True );
    FillSbxMemberObject( rBase, pObj, aSuperList, sal_False );

	ByteString * pStr = aSuperList.First();
	while( pStr )
	{
		delete pStr;
		pStr = aSuperList.Next();
	}
}
 */
#ifdef IDL_COMPILER
/*************************************************************************
|*    SvMetaClass::ReadAttributesSvIdl()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::ReadAttributesSvIdl( SvIdlDataBase & rBase,
										SvTokenStream & rInStm )
{
	SvMetaType::ReadAttributesSvIdl( rBase, rInStm );
	aAutomation.ReadSvIdl( SvHash_Automation(), rInStm );
}

/*************************************************************************
|*    SvMetaClass::WriteAttributesSvIdl()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteAttributesSvIdl( SvIdlDataBase & rBase,
								 SvStream & rOutStm, sal_uInt16 nTab )
{
	SvMetaType::WriteAttributesSvIdl( rBase, rOutStm, nTab );

	if( !aAutomation )
	{
		WriteTab( rOutStm, nTab );
		rOutStm << "//class SvMetaClass" << endl;
		if( !aAutomation )
		{
			WriteTab( rOutStm, nTab );
			aAutomation.WriteSvIdl( SvHash_Automation(), rOutStm );
			rOutStm << ';' << endl;
		}
	}
}

/*************************************************************************
|*    SvMetaClass::ReadContextSvIdl()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase,
                                    SvTokenStream & rInStm )
{
    sal_uInt32  nTokPos = rInStm.Tell();
    SvToken * pTok = rInStm.GetToken_Next();

	if( pTok->Is( SvHash_import() ) )
	{
		SvMetaClass * pClass = rBase.ReadKnownClass( rInStm );
		if( pClass )
		{
			SvClassElementRef xEle = new SvClassElement();
			xEle->SetClass( pClass );
			aClassList.Append( xEle );

		    if( rInStm.Read( '[' ) )
		    {
			    pTok = rInStm.GetToken_Next();
				if( pTok->Is( SvHash_Automation() ) )
				{
		        	if( rInStm.Read( ']' ) )
					{
						if( xAutomationInterface.Is() )
						{
				            // Fehler setzen
				            rBase.SetError( "Automation allready set",
											rInStm.GetToken() );
				            rBase.WriteError( rInStm );
						}
						xAutomationInterface = pClass;
						xEle->SetAutomation( sal_True );
					}
					else
					{
			            // Fehler setzen
			            rBase.SetError( "missing ]", rInStm.GetToken() );
			            rBase.WriteError( rInStm );
					}
				}
				else
				{
		            // Fehler setzen
		            rBase.SetError( "only attribute Automation allowed",
									rInStm.GetToken() );
		            rBase.WriteError( rInStm );
				}
		    }
			pTok = rInStm.GetToken();
			if( pTok->IsString() )
			{
				xEle->SetPrefix( pTok->GetString() );
			    rInStm.GetToken_Next();
			}
			return;
		}
		else
		{
	        // Fehler setzen
	        rBase.SetError( "unknown imported interface", rInStm.GetToken() );
	        rBase.WriteError( rInStm );
		}
	}
	else
	{
		rInStm.Seek( nTokPos );
		SvMetaType * pType = rBase.ReadKnownType( rInStm );

	    sal_Bool bOk = sal_False;
		SvMetaAttributeRef xAttr;
		if( !pType || pType->IsItem() )
		{
			xAttr = new SvMetaSlot( pType );
		    if( xAttr->ReadSvIdl( rBase, rInStm ) )
			    bOk = xAttr->Test( rBase, rInStm );
		}
		else
		{
		    xAttr = new SvMetaAttribute( pType );
		    if( xAttr->ReadSvIdl( rBase, rInStm ) )
			    bOk = xAttr->Test( rBase, rInStm );
		}

		if( bOk )
			bOk = TestAttribute( rBase, rInStm, *xAttr );
		if( bOk )
		{
			if( !xAttr->GetSlotId().IsSet() )
			{
				SvNumberIdentifier aI;
				aI.SetValue( rBase.GetUniqueId() );
				xAttr->SetSlotId( aI );
			}
			aAttrList.Append( xAttr );
			return;
		}
	}
	rInStm.Seek( nTokPos );
}

/*************************************************************************
|*    SvMetaClass::WriteContextSvIdl()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteContextSvIdl
(
	SvIdlDataBase & rBase,
    SvStream & rOutStm,
    sal_uInt16 nTab
)
{
    //SvMetaType::WriteContextSvIdl( rBase, rOutStm, nTab );
	sal_uLong n;
    for( n = 0; n < aAttrList.Count(); n++ )
    {
		WriteTab( rOutStm, nTab );
        aAttrList.GetObject( n )->WriteSvIdl( rBase, rOutStm, nTab );
        rOutStm << ';' << endl;
    }
    for( n = 0; n < aClassList.Count(); n++ )
    {
		SvClassElement * pEle = aClassList.GetObject( n );
		WriteTab( rOutStm, nTab );
        rOutStm << SvHash_import()->GetName().GetBuffer() << ' '
                << pEle->GetPrefix().GetBuffer();
		if( pEle->GetAutomation() )
            rOutStm << " [ " << SvHash_Automation()->GetName().GetBuffer()
					<< " ]";
		if( pEle->GetPrefix().Len() )
            rOutStm << ' ' << pEle->GetPrefix().GetBuffer();
        rOutStm << ';' << endl;
    }
}

/*************************************************************************
|*    SvMetaClass::ReadSvIdl()
|*
|*    Beschreibung
*************************************************************************/
sal_Bool SvMetaClass::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm )
{
	sal_uLong nTokPos = rInStm.Tell();
	if( SvMetaType::ReadHeaderSvIdl( rBase, rInStm ) && GetType() == TYPE_CLASS )
	{
		sal_Bool bOk = sal_True;
		if( rInStm.Read( ':' ) )
		{
			aSuperClass = rBase.ReadKnownClass( rInStm );
			bOk = aSuperClass.Is();
			if( !bOk )
			{
				// Fehler setzen
				rBase.SetError( "unknown super class",
								rInStm.GetToken() );
				rBase.WriteError( rInStm );
			}
		}
		if( bOk )
		{
			rBase.Write( '.' );
			bOk = SvMetaName::ReadSvIdl( rBase, rInStm );
		}
		if( bOk )
			return bOk;
    }
    rInStm.Seek( nTokPos );
    return sal_False;
}

/*************************************************************************
|*    SvMetaClass::TestAttribute()
|*
|*    Beschreibung
*************************************************************************/
sal_Bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm,
								 SvMetaAttribute & rAttr ) const
{
	if ( !rAttr.GetRef() && rAttr.IsA( TYPE( SvMetaSlot ) ) )
	{
		DBG_ERROR( "Neuer Slot : " );
        DBG_ERROR( rAttr.GetSlotId().GetBuffer() );
	}

    for( sal_uLong n = 0; n < aAttrList.Count(); n++ )
    {
		SvMetaAttribute * pS = aAttrList.GetObject( n );
		if( pS->GetName() == rAttr.GetName() )
		{
			// Werte muessen uebereinstimmen
			if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() )
			{
				DBG_ERROR( "Gleicher Name in MetaClass : " );
                DBG_ERROR( pS->GetName().GetBuffer() );
                DBG_ERROR( pS->GetSlotId().GetBuffer() );
                DBG_ERROR( rAttr.GetSlotId().GetBuffer() );

				ByteString aStr( "Attribute's " );
				aStr += pS->GetName();
				aStr += " with different id's";
				rBase.SetError( aStr, rInStm.GetToken() );
				rBase.WriteError( rInStm );
				return sal_False;
		 	}
		}
		else
		{
			sal_uInt32 nId1 = pS->GetSlotId().GetValue();
			sal_uInt32 nId2 = rAttr.GetSlotId().GetValue();
			if( nId1 == nId2 && nId1 != 0 /*&& nId2 != 0 ist ueberfluessig*/ )
			{
				DBG_ERROR( "Gleiche Id in MetaClass : " );
                DBG_ERROR( ByteString::CreateFromInt32( pS->GetSlotId().GetValue() ).GetBuffer() );
                DBG_ERROR( pS->GetSlotId().GetBuffer() );
                DBG_ERROR( rAttr.GetSlotId().GetBuffer() );

				ByteString aStr( "Attribute " );
				aStr += pS->GetName();
				aStr += " and Attribute ";
				aStr += rAttr.GetName();
				aStr += " with equal id's";
				rBase.SetError( aStr, rInStm.GetToken() );
				rBase.WriteError( rInStm );
				return sal_False;
		 	}
		}
    }
	SvMetaClass * pSC = aSuperClass;
    if( pSC )
		return pSC->TestAttribute( rBase, rInStm, rAttr );
    return sal_True;
}

/*************************************************************************
|*    SvMetaClass::WriteSvIdl()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteSvIdl( SvIdlDataBase & rBase, SvStream & rOutStm,
                              sal_uInt16 nTab )
{
	WriteHeaderSvIdl( rBase, rOutStm, nTab );
    if( aSuperClass.Is() )
        rOutStm << " : " << aSuperClass->GetName().GetBuffer();
	rOutStm << endl;
    SvMetaName::WriteSvIdl( rBase, rOutStm, nTab );
	rOutStm << endl;
}

/*************************************************************************
|*    SvMetaClass::WriteOdlMember()
|*
|*    Beschreibung
*************************************************************************/
/*
void SvMetaClass::WriteOdlMembers( ByteStringList & rSuperList,
									sal_Bool bVariable, sal_Bool bWriteTab,
				   					SvIdlDataBase & rBase,
				   					SvStream & rOutStm, sal_uInt16 nTab )
{
	// alle Attribute schreiben
	sal_uLong n;
	for( n = 0; n < aAttrList.Count(); n++ )
	{
		SvMetaAttribute * pAttr = aAttrList.GetObject( n );

		ByteString aMangleName = pAttr->GetMangleName( bVariable );
		ByteString * pS = rBase.FindName( aMangleName, rSuperList );

		if( !pS && pAttr->GetExport() )
		{
			// nicht doppelt
			if( bVariable && pAttr->IsVariable() )
			{
				rSuperList.Insert( new ByteString( aMangleName ), LIST_APPEND );
				pAttr->Write( rBase, rOutStm, nTab +1, WRITE_ODL,
								WA_VARIABLE );
				rOutStm << ';' << endl;
			}
			else if( !bVariable && pAttr->IsMethod() )
			{
				rSuperList.Insert( new ByteString( aMangleName ), LIST_APPEND );
				pAttr->Write( rBase, rOutStm, nTab +1, WRITE_ODL,
								WA_METHOD );
				rOutStm << ';' << endl;
			}
		}
		else
			continue;
	}
	// alle Attribute der importierten Klassen schreiben
	for( n = 0; n < aClassList.Count(); n++ )
	{
		SvClassElement * pEle = aClassList.GetObject( n );
		SvMetaClass * pCl = pEle->GetClass();
		pCl->WriteOdlMembers( rSuperList, bVariable, bWriteTab,
					 			rBase, rOutStm, nTab );
	}
	// alle Attribute der Superklassen schreiben
	SvMetaClass * pSC = aSuperClass;
    if( pSC )
		pSC->WriteOdlMembers( rSuperList, bVariable, bWriteTab,
					 		rBase, rOutStm, nTab );
}
 */

/*************************************************************************
|*    SvMetaClass::Write()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::Write( SvIdlDataBase & rBase, SvStream & rOutStm,
			    		sal_uInt16 nTab,
		 				WriteType nT, WriteAttribute )
{
	rBase.aIFaceName = GetName();
	switch( nT )
	{
		case WRITE_ODL:
		{
            DBG_ERROR( "Not supported anymore!" );
/*
			// Schreibt die Attribute
		    SvMetaName::Write( rBase, rOutStm, nTab, nT, nA );

		    WriteTab( rOutStm, nTab );
            rOutStm << "dispinterface " << GetName().GetBuffer() << endl;
		    WriteTab( rOutStm, nTab );
		    rOutStm << '{' << endl;

		    WriteTab( rOutStm, nTab );
		    rOutStm << "properties:";
		    rOutStm << endl;

			StringList aSuperList;
		    WriteOdlMembers( aSuperList, sal_True, sal_True, rBase, rOutStm, nTab );

		    WriteTab( rOutStm, nTab );
		    rOutStm << "methods:";
		    rOutStm << endl;

		    WriteOdlMembers( aSuperList, sal_False, sal_True, rBase, rOutStm, nTab );

			ByteString * pStr = aSuperList.First();
			while( pStr )
			{
				delete pStr;
				pStr = aSuperList.Next();
			}

		    WriteTab( rOutStm, 1 );
		    rOutStm << '}' << endl;
 */
            break;
		}
		case WRITE_C_SOURCE:
		case WRITE_C_HEADER:
		{
            DBG_ERROR( "Not supported anymore!" );
/*
			StringList aSuperList;
			if( nT == WRITE_C_SOURCE )
			{
                rOutStm << "#pragma code_seg (\"" << GetName().GetBuffer()
					<< "\",\"CODE\")" << endl;
			}
			WriteCFunctions( aSuperList, rBase, rOutStm, nTab, nT );
 */
			break;
		}
		case WRITE_DOCU:
		{
			rOutStm << "<INTERFACE>" << endl
                    << GetName().GetBuffer();
			if ( GetAutomation() )
				rOutStm << " ( Automation ) ";
			rOutStm << endl;
			WriteDescription( rOutStm );
			rOutStm	<< "</INTERFACE>" << endl << endl;

			// alle Attribute schreiben
			sal_uLong n;
			for( n = 0; n < aAttrList.Count(); n++ )
			{
				SvMetaAttribute * pAttr = aAttrList.GetObject( n );
				if( !pAttr->GetHidden() )
				{
					if( pAttr->IsMethod() )
						pAttr->Write( rBase, rOutStm, nTab, nT, WA_METHOD );

					if( pAttr->IsVariable() )
						pAttr->Write( rBase, rOutStm, nTab, nT, WA_VARIABLE );
				}
			}

			break;
		}
        default:
            break;
	}
}

/*************************************************************************
|*    SvMetaClass::WriteSlotParamArray()
|*
|*    Beschreibung
*************************************************************************/
sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase,
										SvSlotElementList & rSlotList,
										SvStream & rOutStm )
{
	sal_uInt16 nCount = 0;
    for( sal_uLong n = 0; n < rSlotList.Count(); n++ )
    {
		SvSlotElement *pEle = rSlotList.GetObject( n );
		SvMetaSlot *pAttr = pEle->xSlot;
		nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm );
    }

	return nCount;
}

/*************************************************************************
|*    SvMetaClass::WriteSlots()
|*
|*    Beschreibung
*************************************************************************/
sal_uInt16 SvMetaClass::WriteSlots( const ByteString & rShellName,
								sal_uInt16 nCount, SvSlotElementList & rSlotList,
								SvIdlDataBase & rBase,
								SvStream & rOutStm )
{
	sal_uInt16 nSCount = 0;
    for( sal_uLong n = 0; n < rSlotList.Count(); n++ )
    {
		rSlotList.Seek(n);
		SvSlotElement * pEle = rSlotList.GetCurObject();
		SvMetaSlot * pAttr = pEle->xSlot;
		nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nCount + nSCount,
										rSlotList, pEle->aPrefix, rBase,
										rOutStm );
    }

	return nSCount;
}

/*************************************************************************
|*    SvMetaClass::InsertSlots()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::InsertSlots( SvSlotElementList& rList, SvULongs& rSuperList,
							SvMetaClassList &rClassList,
							const ByteString & rPrefix, SvIdlDataBase& rBase)
{
	// Wurde diese Klasse schon geschrieben ?
	if ( rClassList.GetPos(this) != LIST_ENTRY_NOTFOUND )
		return;

	rClassList.Insert(this, LIST_APPEND);

	// alle direkten Attribute schreiben
	sal_uLong n;
    for( n = 0; n < aAttrList.Count(); n++ )
    {
		SvMetaAttribute * pAttr = aAttrList.GetObject( n );

		sal_uLong nId = pAttr->GetSlotId().GetValue();
		sal_uInt16 nPos;
		for ( nPos=0; nPos < rSuperList.Count(); nPos++ )
		{
            if ( rSuperList.GetObject(nPos) == nId )
				break;
		}

		if( nPos == rSuperList.Count() )
		{
			// nur schreiben, wenn nicht schon bei SubClass oder
			// importiertem Interface geschrieben
            rSuperList.Insert( nId, nPos );
			pAttr->Insert(rList, rPrefix, rBase);
		}
    }

	// Alle schon von SuperShells importierten Interfaces sollen nicht
	// mehr geschrieben werden
	// Es ist also verboten, da\s Shell und SuperShell die gleiche Klasse
	// direkt importieren !
	if( IsShell() && aSuperClass.Is() )
		aSuperClass->FillClasses( rClassList );

	// alle Attribute der importierten Klassen schreiben, sofern diese nicht
	// schon von der Superklasse importiert wurden
	for( n = 0; n < aClassList.Count(); n++ )
	{
		SvClassElement * pEle = aClassList.GetObject( n );
		SvMetaClass * pCl = pEle->GetClass();
		ByteString rPre = rPrefix;
		if( rPre.Len() && pEle->GetPrefix().Len() )
			rPre += '.';
		rPre += pEle->GetPrefix();

		// Zun"achst die direkt importierten Interfaces schreiben
		pCl->InsertSlots( rList, rSuperList, rClassList, rPre, rBase );
	}

	// Superklassen nur schreiben, wenn keine Shell und nicht in der Liste
	if( !IsShell() && aSuperClass.Is() )
	{
		aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase );
	}
}

/*************************************************************************
|*    SvMetaClass::FillClasses()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::FillClasses( SvMetaClassList & rList )
{
	// Bin ich noch nicht drin ?
	if ( rList.GetPos(this) == LIST_ENTRY_NOTFOUND )
	{
		rList.Insert(this, LIST_APPEND);

		// Meine Imports
		for( sal_uLong n = 0; n < aClassList.Count(); n++ )
		{
			SvClassElement * pEle = aClassList.GetObject( n );
			SvMetaClass * pCl = pEle->GetClass();
			pCl->FillClasses( rList );
		}

		// Meine Superklasse
		if( aSuperClass.Is() )
			aSuperClass->FillClasses( rList );
	}
}


/*************************************************************************
|*    SvMetaClass::WriteSlotStubs()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteSlotStubs( const ByteString & rShellName,
								SvSlotElementList & rSlotList,
                                ByteStringList & rList,
								SvStream & rOutStm )
{
	// alle Attribute schreiben
    for( sal_uLong n = 0; n < rSlotList.Count(); n++ )
    {
		SvSlotElement *pEle = rSlotList.GetObject( n );
		SvMetaSlot *pAttr = pEle->xSlot;
		pAttr->WriteSlotStubs( rShellName, rList, rOutStm );
    }
}

/*************************************************************************
|*    SvMetaClass::WriteSfx()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm )
{
	WriteStars( rOutStm );
    // Klasse definieren
    rOutStm << "#ifdef " << GetName().GetBuffer() << endl;
    rOutStm << "#undef ShellClass" << endl;
    rOutStm << "#undef " << GetName().GetBuffer() << endl;
    rOutStm << "#define ShellClass " << GetName().GetBuffer() << endl;

//    rOutStm << "SFX_TYPELIB(" << GetName().GetBuffer() << ',' << endl
//        << "\t/* library type */"
//        << '"' << ByteString( GetModule()->GetUUId().GetHexName(), RTL_TEXTENCODING_UTF8 ).GetBuffer() << "\"," << endl
//        << "\t\"" << GetModule()->GetTypeLibFileName().GetBuffer() << "\","
//        << ByteString::CreateFromInt32( GetModule()->GetVersion().GetMajorVersion() ).GetBuffer() << ','
//        << ByteString::CreateFromInt32( GetModule()->GetVersion().GetMinorVersion() ).GetBuffer() << ',' << endl
//        << "\t/* shell type   */"
//        << '"';
//    if( xAutomationInterface.Is() )
//        rOutStm << ByteString( xAutomationInterface->GetUUId().GetHexName(), RTL_TEXTENCODING_UTF8 ).GetBuffer();
//    else
//        rOutStm << ByteString( GetUUId().GetHexName(), RTL_TEXTENCODING_UTF8 ).GetBuffer();
//    rOutStm << "\");" << endl << endl;

	// Fuer Interfaces werden kein Slotmaps geschrieben
	if( !IsShell() )
	{
	    rOutStm << "#endif" << endl << endl;
		return;
	}
    // Parameter Array schreiben
    //rOutStm << "SfxArgList " << GetName().GetBuffer() << "ArgMap[] = {" << endl;
    rOutStm << "SFX_ARGUMENTMAP(" << GetName().GetBuffer() << ')' << endl
	    << '{' << endl;

	SvULongs aSuperList;
	SvMetaClassList classList;
	SvSlotElementList aSlotList;
	InsertSlots(aSlotList, aSuperList, classList, ByteString(), rBase);
	sal_uLong n;
	for ( n=0; n<aSlotList.Count(); n++ )
	{
		SvSlotElement *pEle = aSlotList.GetObject( n );
		SvMetaSlot *pSlot = pEle->xSlot;
		pSlot->SetListPos(n);
	}

	sal_uLong nSlotCount = aSlotList.Count();

	// alle Attribute schreiben
	sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm );
    if( nArgCount )
		Back2Delemitter( rOutStm );
	else
    {
		// mindestens einen dummy
		WriteTab( rOutStm, 1 );
		rOutStm << "SFX_ARGUMENT( 0, 0, SfxVoidItem )" << endl;
    }
    rOutStm << endl << "};" << endl << endl;

    ByteStringList aStringList;
	WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm );
	ByteString * pStr = aStringList.First();
	while( pStr )
	{
		delete pStr;
		pStr = aStringList.Next();
	}

    rOutStm << endl;

    // Slotmap schreiben
    rOutStm << "SFX_SLOTMAP_ARG(" << GetName().GetBuffer() << ')' << endl
	    << '{' << endl;

	// alle Attribute schreiben
	WriteSlots( GetName(), 0, aSlotList, rBase, rOutStm );
    if( nSlotCount )
		Back2Delemitter( rOutStm );
	else
    {
		// mindestens einen dummy
		WriteTab( rOutStm, 1 );
        rOutStm << "SFX_SLOT_ARG(" << GetName().GetBuffer()
				<< ", 0, 0, "
				<< "SFX_STUB_PTR_EXEC_NONE,"
				<< "SFX_STUB_PTR_STATE_NONE,"
				<< "0, SfxVoidItem, 0, 0, \"\", 0 )" << endl;
    }
    rOutStm << endl << "};" << endl << "#endif" << endl << endl;

    for( n=0; n<aSlotList.Count(); n++ )
    {
		aSlotList.Seek(n);
		SvSlotElement* pEle = aSlotList.GetCurObject();
		SvMetaSlot* pAttr = pEle->xSlot;
		pAttr->ResetSlotPointer();
	}

	for ( n=0; n<aSlotList.Count(); n++ )
		delete aSlotList.GetObject(n);
}

void SvMetaClass::WriteHelpIds( SvIdlDataBase & rBase, SvStream & rOutStm,
							Table* pTable )
{
    for( sal_uLong n=0; n<aAttrList.Count(); n++ )
    {
		SvMetaAttribute * pAttr = aAttrList.GetObject( n );
		pAttr->WriteHelpId( rBase, rOutStm, pTable );
    }
}

/*************************************************************************
|*    SvMetaShell::WriteSrc()
*************************************************************************/
void SvMetaClass::WriteSrc( SvIdlDataBase & rBase, SvStream & rOutStm,
                             Table * pTable )
{
    for( sal_uLong n=0; n<aAttrList.Count(); n++ )
    {
		SvMetaAttribute * pAttr = aAttrList.GetObject( n );
		pAttr->WriteSrc( rBase, rOutStm, pTable );
    }
}

/*************************************************************************
|*    SvMetaClass::WriteHxx()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteHxx( SvIdlDataBase &, SvStream & rOutStm, sal_uInt16 )
{
	ByteString aSuperName( "SvDispatch" );
	if( GetSuperClass() )
		aSuperName = GetSuperClass()->GetName();
    const char * pSup = aSuperName.GetBuffer();

    rOutStm
    << "class " << GetSvName().GetBuffer()
	<< ": public " << pSup << endl
	<< '{' << endl
	<< "protected:" << endl
    << "\tvirtual SvGlobalName  GetTypeName() const;" << endl
    << "\tvirtual sal_Bool          FillTypeLibInfo( SvGlobalName *, sal_uInt16 * pMajor," << endl
    << "\t                         			     sal_uInt16 * pMinor ) const;" << endl
    << "\tvirtual sal_Bool          FillTypeLibInfo( ByteString * pName, sal_uInt16 * pMajor," << endl;
	rOutStm
    << "\t			                             sal_uInt16 * pMinor ) const;" << endl
    << "\tvirtual void 			Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) = 0;" << endl
	<< "public:" << endl
	<< "\t static SvGlobalName  ClassName()" << endl
    << "\t                      { return SvGlobalName( " << ByteString( GetUUId().GetctorName(), RTL_TEXTENCODING_UTF8 ).GetBuffer() << " ); }" << endl
	<< "};" << endl;
}

/*************************************************************************
|*    SvMetaClass::WriteCxx()
|*
|*    Beschreibung
*************************************************************************/
void SvMetaClass::WriteCxx( SvIdlDataBase &, SvStream & rOutStm, sal_uInt16 )
{
	ByteString aSuperName( "SvDispatch" );
	if( GetSuperClass() )
		aSuperName = GetSuperClass()->GetName();
    const char * pSup = aSuperName.GetBuffer();

	ByteString name = GetSvName();
	// GetTypeName
    rOutStm << "SvGlobalName " << name.GetBuffer() << "::GetTypeName() const" << endl
	<< '{' << endl
	<< "\treturn ClassName();" << endl
	<< '}' << endl;

	SvMetaModule * pMod = GetModule();
	// FillTypeLibInfo
    rOutStm << "sal_Bool " << name.GetBuffer() << "::FillTypeLibInfo( SvGlobalName * pGN," << endl
	<< "\t								 sal_uInt16 * pMajor," << endl
	<< "\t                         		 sal_uInt16 * pMinor ) const" << endl
	<< '{' << endl
    << "\tSvGlobalName aN( " << ByteString( pMod->GetUUId().GetctorName(), RTL_TEXTENCODING_UTF8 ).GetBuffer() << " );" << endl;
	rOutStm << "\t*pGN = aN;" << endl
    << "\t*pMajor = " << ByteString::CreateFromInt32(pMod->GetVersion().GetMajorVersion()).GetBuffer() << ';' << endl
    << "\t*pMinor = " << ByteString::CreateFromInt32(pMod->GetVersion().GetMinorVersion()).GetBuffer() << ';' << endl
	<< "\treturn sal_True;" << endl
	<< '}' << endl;

	// FillTypeLibInfo
    rOutStm << "sal_Bool " << name.GetBuffer() << "::FillTypeLibInfo( ByteString * pName,"
	<< "\t								 sal_uInt16 * pMajor," << endl
	<< "\t                         		 sal_uInt16 * pMinor ) const" << endl;
	rOutStm << '{' << endl
    << "\t*pName = \"" << pMod->GetTypeLibFileName().GetBuffer()  << "\";" << endl
    << "\t*pMajor = " << ByteString::CreateFromInt32(pMod->GetVersion().GetMajorVersion()).GetBuffer() << ';' << endl
    << "\t*pMinor = " << ByteString::CreateFromInt32(pMod->GetVersion().GetMinorVersion()).GetBuffer() << ';' << endl
	<< "\treturn sal_True;" << endl
	<< '}' << endl;

    rOutStm << "void " << name.GetBuffer() << "::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )" << endl
	<< '{' << endl
	<< "\t" << pSup << "::Notify( rBC, rHint );" << endl
	<< '}' << endl;
}

#endif // IDL_COMPILER

