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

#include <stdio.h>
#include	<rtl/alloc.h>
#include	<rtl/ustring.hxx>
#include	<rtl/strbuf.hxx>

#include	"idltype.hxx"
#include	"idloptions.hxx"

using namespace rtl;

//*************************************************************************
// IdlType
//*************************************************************************
IdlType::IdlType(TypeReader& typeReader,
				   const OString& typeName,
				   const TypeManager& typeMgr,
				   const TypeDependency& typeDependencies)
	: m_inheritedMemberCount(0)
	, m_indentLength(0)
	, m_typeName(typeName)
	, m_reader(typeReader)
	, m_typeMgr((TypeManager&)typeMgr)
	, m_dependencies(typeDependencies)
{
	sal_Int32 i = typeName.lastIndexOf('/');
    m_name = typeName.copy( i != -1 ? i+1 : 0 );
}

IdlType::~IdlType()
{

}

sal_Bool IdlType::dump(IdlOptions* pOptions)
	throw( CannotDumpException )
{
	sal_Bool ret = sal_False;

	OString outPath;
	if (pOptions->isValid("-O"))
		outPath = pOptions->getOption("-O");

	OString tmpFileName;
	OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl");

	sal_Bool bFileExists = sal_False;
	sal_Bool bFileCheck = sal_False;

	if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
	{
		bFileExists = fileExists( hFileName );
		ret = sal_True;
	}

	if ( bFileExists && pOptions->isValid("-Gc") )
	{
		tmpFileName	 = createFileNameFromType(outPath, m_typeName, ".tml");
		bFileCheck = sal_True;
	}

	if ( !bFileExists || bFileCheck )
	{
		FileStream hFile;

		if ( bFileCheck )
			hFile.open(tmpFileName);
		else
			hFile.open(hFileName);

		if(!hFile.isValid())
		{
			OString message("cannot open ");
			message += hFileName + " for writing";
			throw CannotDumpException(message);
		}

		ret = dumpHFile(hFile);

		hFile.close();
		if (ret && bFileCheck)
		{
			ret = checkFileContent(hFileName, tmpFileName);
		}
	}

	return ret;
}
sal_Bool IdlType::dumpDependedTypes(IdlOptions* pOptions)
	throw( CannotDumpException )
{
	sal_Bool ret = sal_True;

	TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName));

	TypeUsingSet::const_iterator iter = usingSet.begin();
	OString typeName;
	sal_uInt32 index = 0;
	while (iter != usingSet.end())
	{
		typeName = (*iter).m_type;
		if ((index = typeName.lastIndexOf(']')) > 0)
			typeName = typeName.copy(index + 1);

		if ( getBaseType(typeName).isEmpty() )
		{
			if (!produceType(typeName,
						   	 m_typeMgr,
							 m_dependencies,
							 pOptions))
			{
				fprintf(stderr, "%s ERROR: %s\n",
						pOptions->getProgramName().getStr(),
						OString("cannot dump Type '" + typeName + "'").getStr());
				exit(99);
			}
		}
		++iter;
	}

	return ret;
}

OString IdlType::dumpHeaderDefine(FileStream& o, sal_Char* prefix )
{
	if (m_typeName.equals("/"))
	{
		m_typeName = "global";
	}

	sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix);

	OStringBuffer tmpBuf(length);

	tmpBuf.append('_');
	tmpBuf.append(m_typeName);
	tmpBuf.append('_');
	tmpBuf.append(prefix);
	tmpBuf.append('_');

	OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());

	o << "#ifndef " << tmp << "\n#define " << tmp << "\n";

	return tmp;
}

void IdlType::dumpDefaultHIncludes(FileStream& o)
{
}

void IdlType::dumpInclude(FileStream& o, const OString& genTypeName, const OString& typeName, sal_Char* prefix )
{
	sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix);

	OStringBuffer tmpBuf(length);

	tmpBuf.append('_');
	tmpBuf.append(typeName);
	tmpBuf.append('_');
	tmpBuf.append(prefix);
	tmpBuf.append('_');

	OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase());

	length = 1 + typeName.getLength() + strlen(prefix);

	tmpBuf.ensureCapacity(length);
	tmpBuf.append(typeName);
	tmpBuf.append('.');
	tmpBuf.append(prefix);

	o << "#ifndef " << tmp << "\n#include <";
	tmp = tmpBuf.makeStringAndClear();

    sal_Int32 nIndex = 0;
    do
	{
		genTypeName.getToken(0, '/', nIndex);
	 	o << "../";
	} while( nIndex != -1 );

//  	sal_Int32 nSlashes = genTypeName.getTokenCount( '/');
//  	for( sal_Int32 i = 1; i < nSlashes; i++ )
//  		o << "../";
	o << tmp;
	o << ">\n#endif\n";
}

void IdlType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix)
{
	TypeUsingSet usingSet(m_dependencies.getDependencies(typeName));

	TypeUsingSet::const_iterator iter = usingSet.begin();

	OString 	sPrefix(OString(prefix).toAsciiUpperCase());
	sal_uInt32 	index = 0;
	sal_uInt32 	seqNum = 0;
	OString 	relType;
	while (iter != usingSet.end())
	{
		index = (*iter).m_type.lastIndexOf(']');
		seqNum = (index > 0 ? ((index+1) / 2) : 0);

		relType = (*iter).m_type;
		if (index > 0)
			relType = relType.copy(index+1);


		OString defPrefix("IDL");

		if ( getBaseType(relType).isEmpty() &&
			m_typeName != relType)
		{
			if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
			{
				if (!((*iter).m_use & TYPEUSE_SUPER))
				{
					o << "\n";
					dumpNameSpace(o, sal_True, sal_False, relType);
					o << "\ninterface " << scopedName(m_typeName, relType, sal_True) << ";\n";
					dumpNameSpace(o, sal_False, sal_False, relType);
					o << "\n\n";
				}
			}
			dumpInclude(o, typeName, relType, prefix);
		}
		else if (relType == "type")
		{
			o << "module CORBA {\n"
			  << "\tinterface TypeCode;\n"
			  << "};\n\n";
		}

		if( seqNum != 0 )
		{
			// write typedef for sequences to support Rational Rose 2000 import
			OString aST = relType;
			OString aScope;
			dumpNameSpace( o, sal_True, sal_False, relType );
			for( sal_uInt32 i = 0; i < seqNum; i++ )
			{
				o << "typedef sequence< " << scopedName("", aST) << " > ";

				if( i == 0 )
				{
					aST = aST.replace( '/', '_' );
					aST = aST.replace( ' ', '_' );
				}
				aST = aST + "_Sequence" ;
				o << aST << ";\n";
			}
			dumpNameSpace( o, sal_False, sal_False, relType );
		}
		++iter;
	}
}

void IdlType::dumpNameSpace(FileStream& o, sal_Bool bOpen, sal_Bool bFull, const OString& type)
{
	OString typeName(type);
	sal_Bool bOneLine = sal_True;
	if ( typeName.isEmpty() )
	{
		typeName = m_typeName;
		bOneLine = sal_False;
	}

	if (typeName == "/")
		return;

	if (typeName.indexOf( '/' ) == -1 && !bFull)
		return;

	if (!bFull)
        typeName = typeName.copy( 0, typeName.lastIndexOf( '/' ) );

	if (bOpen)
	{
        sal_Int32 nIndex = 0;
		do
		{
			o << "module " << typeName.getToken(0, '/', nIndex);
			if (bOneLine)
				o << " { ";
			else
			 	o << "\n{\n";
		} while( nIndex != -1 );
	} else
	{
        sal_Int32 nPos = 0;
		do
		{
            nPos = typeName.lastIndexOf( '/' );
            o << "};";
            if( bOneLine )
                o << " ";
            else
                o << " /* " << typeName.copy( nPos+1 ) << " */\n";
            if( nPos != -1 )
                typeName = typeName.copy( 0, nPos );
        } while( nPos != -1 );
	}
}


sal_uInt32 IdlType::getMemberCount()
{
	sal_uInt32 count = m_reader.getMethodCount();

	sal_uInt32 fieldCount = m_reader.getFieldCount();
	RTFieldAccess access = RT_ACCESS_INVALID;
	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
			count++;
	}
	return count;
}

sal_uInt32 IdlType::checkInheritedMemberCount(const TypeReader* pReader)
{
	sal_Bool bSelfCheck = sal_True;
	if (!pReader)
	{
		bSelfCheck = sal_False;
		pReader = &m_reader;
	}

	sal_uInt32 count = 0;
	OString superType(pReader->getSuperTypeName());
	if ( !superType.isEmpty() )
	{
		TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
		if ( aSuperReader.isValid() )
		{
			count = checkInheritedMemberCount(&aSuperReader);
		}
	}

	if (bSelfCheck)
	{
		count += pReader->getMethodCount();
		sal_uInt32 fieldCount = pReader->getFieldCount();
		RTFieldAccess access = RT_ACCESS_INVALID;
		for (sal_uInt16 i=0; i < fieldCount; i++)
		{
			access = pReader->getFieldAccess(i);

			if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
			{
				count++;
			}
		}
	}

	return count;
}

sal_uInt32 IdlType::getInheritedMemberCount()
{
	if (m_inheritedMemberCount == 0)
	{
		m_inheritedMemberCount = checkInheritedMemberCount(0);
	}

	return m_inheritedMemberCount;
}


void IdlType::dumpType(FileStream& o, const OString& type )
	throw( CannotDumpException )
{
	OString sType(checkRealBaseType(type, sal_True));
	sal_uInt32 index = sType.lastIndexOf(']');
	sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0);

	OString relType = (index > 0 ? (sType).copy(index+1) : type);

	RTTypeClass typeClass = m_typeMgr.getTypeClass(relType);

	sal_uInt32 i;
/*
	for (i=0; i < seqNum; i++)
	{
		//o << "sequence< ";
	}
*/
	switch (typeClass)
	{
		case RT_TYPE_INVALID:
			{
				OString tmp(getBaseType(relType));
				if ( !tmp.isEmpty() )
				{
					tmp = tmp.replace( ' ', '_' );
					o << tmp;
				} else
					throw CannotDumpException("Unknown type '" + relType + "', incomplete type library.");
			}
			break;
		case RT_TYPE_INTERFACE:
		case RT_TYPE_STRUCT:
		case RT_TYPE_ENUM:
		case RT_TYPE_TYPEDEF:
		case RT_TYPE_EXCEPTION:
				if( seqNum )
				{
					OString aST = relType.replace( '/', '_' );
					aST = aST.replace( ' ', '_' );
					o << aST;
				}
				else
					o << scopedName(m_typeName, relType);
			break;
	}

	for (i=0; i < seqNum; i++)
	{
		//o << " >";
		// use typedef for sequences to support Rational Rose 2000 import
		o << "_Sequence";
	}
}

OString	IdlType::getBaseType(const OString& type)
{
	if (type.equals("long"))
		return type;
	if (type.equals("short"))
		return type;
	if (type.equals("hyper"))
		return "long long";
	if (type.equals("string"))
		return "string";
	if (type.equals("boolean"))
		return type;
	if (type.equals("char"))
		return "char";
	if (type.equals("byte"))
		return "byte";
	if (type.equals("any"))
		return type;
	if (type.equals("type"))
		return "CORBA::TypeCode";
	if (type.equals("float"))
		return type;
	if (type.equals("double"))
		return type;
	if (type.equals("octet"))
		return type;
	if (type.equals("void"))
		return type;
	if (type.equals("unsigned long"))
		return type;
	if (type.equals("unsigned short"))
		return type;
	if (type.equals("unsigned hyper"))
		return "unsigned long long";

	return OString();
}

void IdlType::dumpIdlGetType(FileStream& o, const OString& type, sal_Bool bDecl, IdlTypeDecl eDeclFlag)
{
	OString sType( checkRealBaseType(type, sal_True) );
	sal_uInt32 index = sType.lastIndexOf(']');
	OString relType = (index > 0 ? (sType).copy(index+1) : type);

	if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES)
	{
	 	if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
		{
			o << indent() << "getIdlType( (";
			dumpType(o, type);
			o << "*)0 )";

			if (bDecl)
				o << ";\n";
		}
	} else
	{
		if (isBaseType(type))
		{
			return;
		} else
		{
			if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES &&
				m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE)
				return;

//			if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF)
//			{
//				o << indent() << "get_" << type.replace('/', '_') << "_Type()";
//			} else
//			{
				o << indent() << "getIdlType( (";
				dumpType(o, type);
				o << "*)0 )";
//			}
		}
		if (bDecl)
			o << ";\n";
	}
}

BASETYPE IdlType::isBaseType(const OString& type)
{
	if (type.equals("long"))
		return BT_LONG;
	if (type.equals("short"))
		return BT_SHORT;
	if (type.equals("hyper"))
		return BT_HYPER;
	if (type.equals("string"))
		return BT_STRING;
	if (type.equals("boolean"))
		return BT_BOOLEAN;
	if (type.equals("char"))
		return BT_CHAR;
	if (type.equals("byte"))
		return BT_BYTE;
	if (type.equals("any"))
		return BT_ANY;
	if (type.equals("float"))
		return BT_FLOAT;
	if (type.equals("double"))
		return BT_DOUBLE;
	if (type.equals("void"))
		return BT_VOID;
	if (type.equals("unsigned long"))
		return BT_UNSIGNED_LONG;
	if (type.equals("unsigned short"))
		return BT_UNSIGNED_SHORT;
	if (type.equals("unsigned hyper"))
		return BT_UNSIGNED_HYPER;

	return BT_INVALID;
}

OString	IdlType::checkSpecialIdlType(const OString& type)
{
	OString baseType(type);

	RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();

	RegistryKey 	key;
	sal_uInt8*		pBuffer=NULL;
	RTTypeClass 	typeClass;
	sal_Bool 		isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
	TypeReader		reader;

	while (isTypeDef)
	{
		reader = m_typeMgr.getTypeReader(baseType);

		if (reader.isValid())
		{
			typeClass = reader.getTypeClass();

			if (typeClass == RT_TYPE_TYPEDEF)
				baseType = reader.getSuperTypeName();
			else
				isTypeDef = sal_False;
		} else
		{
			break;
		}
	}

	return baseType;
}

OString	IdlType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly)
{
	sal_uInt32 index = type.lastIndexOf(']');
	OString baseType = (index > 0 ? ((OString)type).copy(index+1) : type);
	OString seqPrefix = (index > 0 ? ((OString)type).copy(0, index+1) : OString());

	RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader();

	RegistryKey 	key;
	sal_uInt8*		pBuffer=NULL;
	RTTypeClass 	typeClass;
	sal_Bool 		mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF);
	TypeReader		reader;

	while (mustBeChecked)
	{
		reader = m_typeMgr.getTypeReader(baseType);

		if (reader.isValid())
		{
			typeClass = reader.getTypeClass();

			if (typeClass == RT_TYPE_TYPEDEF)
			{
				baseType = reader.getSuperTypeName();
				index = baseType.lastIndexOf(']');
		  		if (index > 0)
				{
					seqPrefix += baseType.copy(0, index+1);
					baseType = baseType.copy(index+1);
				}
			} else
				mustBeChecked = sal_False;
		} else
		{
			break;
		}
	}

	if ( bResolveTypeOnly )
		baseType = seqPrefix + baseType;

	return baseType;
}

void IdlType::dumpConstantValue(FileStream& o, sal_uInt16 index)
{
	RTConstValue constValue = m_reader.getFieldConstValue(index);

	switch (constValue.m_type)
	{
		case RT_TYPE_BOOL:
			if (constValue.m_value.aBool)
				o << "true";
			else
				o << "false";
			break;
		case RT_TYPE_BYTE:
			{
				char tmp[16];
                snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte);
				o << tmp;
			}
			break;
		case RT_TYPE_INT16:
			o << constValue.m_value.aShort;
			break;
		case RT_TYPE_UINT16:
			o << constValue.m_value.aUShort;
			break;
		case RT_TYPE_INT32:
			o << constValue.m_value.aLong;
			break;
		case RT_TYPE_UINT32:
			o << constValue.m_value.aULong;
			break;
		case RT_TYPE_INT64:
            {
                ::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) );
                o << tmp.getStr();
            }
			break;
		case RT_TYPE_UINT64:
            {
                ::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) );
                o << tmp.getStr();
            }
			break;
		case RT_TYPE_FLOAT:
            {
                ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) );
                o << tmp.getStr();
            }
			break;
		case RT_TYPE_DOUBLE:
            {
                ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) );
                o << tmp.getStr();
            }
			break;
		case RT_TYPE_STRING:
			{
				::rtl::OUString aUStr(constValue.m_value.aString);
				::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US);
				o << "\"" << aStr.getStr() << "\")";
			}
			break;
	}
}

void IdlType::inc(sal_uInt32 num)
{
	m_indentLength += num;
}

void IdlType::dec(sal_uInt32 num)
{
	if (m_indentLength - num < 0)
		m_indentLength = 0;
	else
		m_indentLength -= num;
}

OString IdlType::indent()
{
	OStringBuffer tmp(m_indentLength);

	for (sal_uInt32 i=0; i < m_indentLength; i++)
	{
		tmp.append(' ');
	}
	return tmp.makeStringAndClear();
}

OString	IdlType::indent(sal_uInt32 num)
{
	OStringBuffer tmp(m_indentLength + num);

	for (sal_uInt32 i=0; i < m_indentLength + num; i++)
	{
		tmp.append(' ');
	}
	return tmp.makeStringAndClear();
}

//*************************************************************************
// InterfaceType
//*************************************************************************
InterfaceType::InterfaceType(TypeReader& typeReader,
			 				 const OString& typeName,
							 const TypeManager& typeMgr,
							 const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
	m_inheritedMemberCount = 0;
	m_hasAttributes = sal_False;
	m_hasMethods = sal_False;
}

InterfaceType::~InterfaceType()
{

}

sal_Bool InterfaceType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";
	dumpDepIncludes(o, m_typeName, "idl");
	o << "\n";
	dumpNameSpace(o);

	// write documentation
	OString aDoc = m_reader.getDoku();
	if( !aDoc.isEmpty() )
		o << "/**\n" << aDoc << "\n*/";
	o << "\ninterface " << m_name;

	OString superType(m_reader.getSuperTypeName());
	if ( !superType.isEmpty() )
		o << " : " << scopedName(m_typeName, superType);

	o << "\n{\n";
	inc();

	dumpAttributes(o);
	dumpMethods(o);

	dec();
	o << "};\n\n";

	dumpNameSpace(o, sal_False);

//	o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n"
//	  << "class Type;\n} } } }\n\n";

	o << "#endif /* "<< headerDefine << "*/" << "\n";
	return sal_True;
}

void InterfaceType::dumpAttributes(FileStream& o)
{
	sal_uInt32 fieldCount = m_reader.getFieldCount();
	sal_Bool first=sal_True;

	RTFieldAccess access = RT_ACCESS_INVALID;
	OString fieldName;
	OString fieldType;
	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
			continue;

		fieldName = m_reader.getFieldName(i);
		fieldType = m_reader.getFieldType(i);

		if (first)
		{
			first = sal_False;
			o << "\n";
		}

		// write documentation
		OString aDoc = m_reader.getFieldDoku(i);
		if( !aDoc.isEmpty() )
			o << "/**\n" << aDoc << "\n*/\n";

		if (access == RT_ACCESS_READONLY)
			o << indent() << "readonly attribute ";
		else
			o << indent() << "attribute ";
		dumpType(o, fieldType);
		o << " " << fieldName << ";\n";
	}
}

void InterfaceType::dumpMethods(FileStream& o)
{
	sal_uInt32 methodCount = m_reader.getMethodCount();

	OString methodName, returnType, paramType, paramName;
	sal_uInt32 paramCount = 0;
	sal_uInt32 excCount = 0;
	RTMethodMode methodMode = RT_MODE_INVALID;
	RTParamMode	 paramMode = RT_PARAM_INVALID;

	sal_Bool bRef = sal_False;
	sal_Bool bConst = sal_False;
	sal_Bool bWithRunTimeExcp = sal_True;

	for (sal_Int16 i=0; i < methodCount; i++)
	{
		methodName = m_reader.getMethodName(i);
		returnType = m_reader.getMethodReturnType(i);
		paramCount = m_reader.getMethodParamCount(i);
		excCount = m_reader.getMethodExcCount(i);
		methodMode = m_reader.getMethodMode(i);

		if ( methodName.equals("acquire") || methodName.equals("release") )
		{
			bWithRunTimeExcp = sal_False;
		}

		// write documentation
		OString aDoc = m_reader.getMethodDoku(i);
		if( !aDoc.isEmpty() )
			o << "/**\n" << aDoc << "\n*/\n";

		o << indent();
		dumpType(o, returnType);
		o << " " << methodName << "( ";
		sal_uInt16 j;
		for (j=0; j < paramCount; j++)
		{
			paramName =	m_reader.getMethodParamName(i, j);
			paramType =	m_reader.getMethodParamType(i, j);
			paramMode = m_reader.getMethodParamMode(i, j);

			switch (paramMode)
			{
				case RT_PARAM_IN:
					o << "in ";
					break;
				case RT_PARAM_OUT:
					o << "out ";
					break;
				case RT_PARAM_INOUT:
					o << "inout ";
					break;
					break;
			}

			dumpType(o, paramType);
			if( paramName == "Object" )
				o << " _Object";
			else
				o << " " << paramName;

			if (j+1 < paramCount) o << ", ";
		}
		o << " )";

		if( excCount )
		{
			o << " raises(";
			OString excpName;
			sal_Bool bWriteComma = sal_False;
			sal_Bool bRTExceptionWritten = sal_False;
			for (j=0; j < excCount; j++)
			{
				excpName = m_reader.getMethodExcType(i, j);
				if( bWriteComma )
					o << ", ";
				o << scopedName(m_typeName, excpName);
				bWriteComma = sal_True;

				if(excpName == "com/sun/star/uno/RuntimeException")
					bRTExceptionWritten = sal_True;
			}

			if ( bWithRunTimeExcp && !bRTExceptionWritten )
			{
				if( bWriteComma )
					o << ", ";
				o << "::com::sun::star::uno::RuntimeException";
			}

			o << ");\n";
		}
		else if ( bWithRunTimeExcp )
		{
			o << "raises( ::com::sun::star::uno::RuntimeException );\n";
		}
		else
		{
			o << ";\n";
		}
	}
}


sal_uInt32 InterfaceType::getMemberCount()
{
	sal_uInt32 count = m_reader.getMethodCount();

	if (count)
		m_hasMethods = sal_True;

	sal_uInt32 fieldCount = m_reader.getFieldCount();
	RTFieldAccess access = RT_ACCESS_INVALID;
	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
		{
			m_hasAttributes = sal_True;
			count++;
		}
	}
	return count;
}

sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader)
{
	sal_uInt32 cout = 0;
	sal_Bool bSelfCheck = sal_True;
	if (!pReader)
	{
		bSelfCheck = sal_False;
		pReader = &m_reader;
	}

	sal_uInt32 count = 0;
	OString superType(pReader->getSuperTypeName());
	if ( !superType.isEmpty() )
	{
		TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));
		if (aSuperReader.isValid())
		{
			count = checkInheritedMemberCount(&aSuperReader);
		}
	}

	if (bSelfCheck)
	{
		count += pReader->getMethodCount();
		sal_uInt32 fieldCount = pReader->getFieldCount();
		RTFieldAccess access = RT_ACCESS_INVALID;
		for (sal_uInt16 i=0; i < fieldCount; i++)
		{
			access = pReader->getFieldAccess(i);

			if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID)
			{
				count++;
			}
		}
	}

	return count;
}

sal_uInt32 InterfaceType::getInheritedMemberCount()
{
	if (m_inheritedMemberCount == 0)
	{
		m_inheritedMemberCount = checkInheritedMemberCount(0);
	}

	return m_inheritedMemberCount;
}



//*************************************************************************
// ModuleType
//*************************************************************************
ModuleType::ModuleType(TypeReader& typeReader,
			 		   const OString& typeName,
					   const TypeManager& typeMgr,
					   const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}

ModuleType::~ModuleType()
{

}

sal_Bool ModuleType::dump(IdlOptions* pOptions)
	throw( CannotDumpException )
{
	sal_Bool ret = sal_False;

	OString outPath;
	if (pOptions->isValid("-O"))
		outPath = pOptions->getOption("-O");

	OString tmpName(m_typeName);

	if (tmpName.equals("/"))
		tmpName = "global";
	else
//		tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/');
		tmpName += "/" + m_name;

	OString tmpFileName;
	OString hFileName = createFileNameFromType(outPath, tmpName, ".idl");

	sal_Bool bFileExists = sal_False;
	sal_Bool bFileCheck = sal_False;

	if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
	{
		bFileExists = fileExists( hFileName );
		ret = sal_True;
	}

	if ( bFileExists && pOptions->isValid("-Gc") )
	{
		tmpFileName	 = createFileNameFromType(outPath, m_typeName, ".tml");
		bFileCheck = sal_True;
	}

	if ( !bFileExists || bFileCheck )
	{
		FileStream hFile;

		if ( bFileCheck )
			hFile.open(tmpFileName);
		else
			hFile.open(hFileName);

		if(!hFile.isValid())
		{
			OString message("cannot open ");
			message += hFileName + " for writing";
			throw CannotDumpException(message);
		}

		ret = dumpHFile(hFile);

		hFile.close();
		if (ret && bFileCheck)
		{
			ret = checkFileContent(hFileName, tmpFileName);
		}
	}

	return ret;
}

sal_Bool ModuleType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";
	dumpDepIncludes(o, m_typeName, "idl");
	o << "\n";

	dumpNameSpace(o, sal_True, sal_True);
	o << "\n";

	sal_uInt32 		fieldCount = m_reader.getFieldCount();
	RTFieldAccess 	access = RT_ACCESS_INVALID;
	OString 		fieldName;
	OString 		fieldType;
	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access == RT_ACCESS_CONST)
		{
			fieldName = m_reader.getFieldName(i);
			fieldType = m_reader.getFieldType(i);

			o << "const ";
			dumpType(o, fieldType);
			o << " " << fieldName << " = ";
			dumpConstantValue(o, i);
			o << ";\n";
		}
	}

	o << "\n";
	dumpNameSpace(o, sal_False, sal_True);
	o << "\n#endif /* "<< headerDefine << "*/" << "\n";

	return sal_True;
}

sal_Bool ModuleType::hasConstants()
{
	sal_uInt32 		fieldCount = m_reader.getFieldCount();
	RTFieldAccess 	access = RT_ACCESS_INVALID;

	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access == RT_ACCESS_CONST)
			return sal_True;
	}

	return sal_False;
}

//*************************************************************************
// ConstantsType
//*************************************************************************
ConstantsType::ConstantsType(TypeReader& typeReader,
				 		     const OString& typeName,
						     const TypeManager& typeMgr,
						     const TypeDependency& typeDependencies)
	: ModuleType(typeReader, typeName, typeMgr, typeDependencies)
{
}

ConstantsType::~ConstantsType()
{

}

sal_Bool ConstantsType::dump(IdlOptions* pOptions)
	throw( CannotDumpException )
{
	sal_Bool ret = sal_False;

	OString outPath;
	if (pOptions->isValid("-O"))
		outPath = pOptions->getOption("-O");

	OString tmpFileName;
	OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl");

	sal_Bool bFileExists = sal_False;
	sal_Bool bFileCheck = sal_False;

	if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") )
	{
		bFileExists = fileExists( hFileName );
		ret = sal_True;
	}

	if ( bFileExists && pOptions->isValid("-Gc") )
	{
		tmpFileName	 = createFileNameFromType(outPath, m_typeName, ".tml");
		bFileCheck = sal_True;
	}

	if ( !bFileExists || bFileCheck )
	{
		FileStream hFile;

		if ( bFileCheck )
			hFile.open(tmpFileName);
		else
			hFile.open(hFileName);

		if(!hFile.isValid())
		{
			OString message("cannot open ");
			message += hFileName + " for writing";
			throw CannotDumpException(message);
		}

		ret = dumpHFile(hFile);

		hFile.close();
		if (ret && bFileCheck)
		{
			ret = checkFileContent(hFileName, tmpFileName);
		}
	}

	return ret;
}

//*************************************************************************
// StructureType
//*************************************************************************
StructureType::StructureType(TypeReader& typeReader,
			 				 const OString& typeName,
							 const TypeManager& typeMgr,
							 const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}

StructureType::~StructureType()
{

}

sal_Bool StructureType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";
	dumpDepIncludes(o, m_typeName, "idl");
	o << "\n";

	dumpNameSpace(o);

	// write documentation
	OString aDoc = m_reader.getDoku();
	if( !aDoc.isEmpty() )
		o << "/**\n" << aDoc << "\n*/";

	o << "\nstruct " << m_name;
	o << "\n{\n";
	inc();

	OString superType(m_reader.getSuperTypeName());
	if ( !superType.isEmpty() )
		dumpSuperMember(o, superType);

	sal_uInt32 		fieldCount = m_reader.getFieldCount();
	RTFieldAccess 	access = RT_ACCESS_INVALID;
	OString 		fieldName;
	OString 		fieldType;
	sal_uInt16 		i=0;

	for (i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
			continue;

		fieldName = m_reader.getFieldName(i);
		fieldType = m_reader.getFieldType(i);

		// write documentation
		OString aDoc = m_reader.getFieldDoku(i);
		if( !aDoc.isEmpty() )
			o << "/**\n" << aDoc << "\n*/";

		o << indent();
		dumpType(o, fieldType);
		o << " " << fieldName << ";\n";
	}

	dec();
	o << "};\n\n";

	dumpNameSpace(o, sal_False);

	o << "#endif /* "<< headerDefine << "*/" << "\n";

	return sal_True;
}

void StructureType::dumpSuperMember(FileStream& o, const OString& superType)
{
	if ( !superType.isEmpty() )
	{
		TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));

		if (aSuperReader.isValid())
		{
			dumpSuperMember(o, aSuperReader.getSuperTypeName());

			sal_uInt32 		fieldCount = aSuperReader.getFieldCount();
			RTFieldAccess 	access = RT_ACCESS_INVALID;
			OString 		fieldName;
			OString 		fieldType;
			for (sal_uInt16 i=0; i < fieldCount; i++)
			{
				access = aSuperReader.getFieldAccess(i);

				if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
					continue;

				fieldName = aSuperReader.getFieldName(i);
				fieldType = aSuperReader.getFieldType(i);

				// write documentation
				OString aDoc = aSuperReader.getFieldDoku(i);
				if( !aDoc.isEmpty() )
					o << "/**\n" << aDoc << "\n*/";

				o << indent();
				dumpType(o, fieldType);
				o << " ";
				o << fieldName << ";\n";
			}
		}
	}
}

//*************************************************************************
// ExceptionType
//*************************************************************************
ExceptionType::ExceptionType(TypeReader& typeReader,
			 				 const OString& typeName,
							 const TypeManager& typeMgr,
							 const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}

ExceptionType::~ExceptionType()
{

}

sal_Bool ExceptionType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";
	dumpDepIncludes(o, m_typeName, "idl");
	o << "\n";

	dumpNameSpace(o);

	// write documentation
	OString aDoc = m_reader.getDoku();
	if( !aDoc.isEmpty() )
		o << "/**\n" << aDoc << "\n*/";

	o << "\nexception " << m_name;
	o << "\n{\n";
	inc();

	// Write extra member for derived exceptions
	o << indent() << "/*extra member to hold a derived exception */\n";
	o << indent() << "any _derivedException;\n";
	OString superType(m_reader.getSuperTypeName());
	if ( !superType.isEmpty() )
		dumpSuperMember(o, superType);

	sal_uInt32 		fieldCount = m_reader.getFieldCount();
	RTFieldAccess 	access = RT_ACCESS_INVALID;
	OString 		fieldName;
	OString 		fieldType;
	sal_uInt16 		i = 0;

	for (i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
			continue;

		fieldName = m_reader.getFieldName(i);
		fieldType = m_reader.getFieldType(i);

		// write documentation
		OString aDoc = m_reader.getFieldDoku(i);
		if( !aDoc.isEmpty() )
			o << "/**\n" << aDoc << "\n*/";

		o << indent();
		dumpType(o, fieldType);
		o << " " << fieldName << ";\n";
	}


	dec();
	o << "};\n\n";

	dumpNameSpace(o, sal_False);

	o << "#endif /* "<< headerDefine << "*/" << "\n";

	return sal_True;
}

void ExceptionType::dumpSuperMember(FileStream& o, const OString& superType)
{
	if ( !superType.isEmpty() )
	{
		TypeReader aSuperReader(m_typeMgr.getTypeReader(superType));

		if (aSuperReader.isValid())
		{
			dumpSuperMember(o, aSuperReader.getSuperTypeName());

			sal_uInt32 		fieldCount = aSuperReader.getFieldCount();
			RTFieldAccess 	access = RT_ACCESS_INVALID;
			OString 		fieldName;
			OString 		fieldType;
			for (sal_uInt16 i=0; i < fieldCount; i++)
			{
				access = aSuperReader.getFieldAccess(i);

				if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID)
					continue;

				fieldName = aSuperReader.getFieldName(i);
				fieldType = aSuperReader.getFieldType(i);

				// write documentation
				OString aDoc = aSuperReader.getFieldDoku(i);
				if( !aDoc.isEmpty() )
					o << "/**\n" << aDoc << "\n*/";

				o << indent();
				dumpType(o, fieldType);
				o << " ";
				o << fieldName << ";\n";
			}
		}
	}
}

//*************************************************************************
// EnumType
//*************************************************************************
EnumType::EnumType(TypeReader& typeReader,
			 	   const OString& typeName,
				   const TypeManager& typeMgr,
				   const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}

EnumType::~EnumType()
{

}

sal_Bool EnumType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";

	dumpNameSpace(o);

	// write documentation
	OString aDoc = m_reader.getDoku();
	if( !aDoc.isEmpty() )
		o << "/**\n" << aDoc << "\n*/";

	o << "\nenum " << m_name << "\n{\n";
	inc();

	sal_uInt32 		fieldCount = m_reader.getFieldCount();
	RTFieldAccess 	access = RT_ACCESS_INVALID;
	RTConstValue	constValue;
	OString 		fieldName;
	sal_uInt32		value=0;
	for (sal_uInt16 i=0; i < fieldCount; i++)
	{
		access = m_reader.getFieldAccess(i);

		if (access != RT_ACCESS_CONST)
			continue;

		fieldName = m_reader.getFieldName(i);
		constValue = m_reader.getFieldConstValue(i);

		if (constValue.m_type == RT_TYPE_INT32)
			value = constValue.m_value.aLong;
		else
			value++;

		/* doesn't work with rational rose 2000
		// write documentation
		OString aDoc = m_reader.getFieldDoku(i);
		if( aDoc.getLength() )
		*/
		//	o << "/**\n" << aDoc << "\n*/\n";
		o << indent() << fieldName;
		if( i +1 < fieldCount )
			o << ",\n";
	}

	dec();
	o << "\n};\n\n";

	dumpNameSpace(o, sal_False);

	o << "#endif /* "<< headerDefine << "*/" << "\n";

	return sal_True;
}


//*************************************************************************
// TypeDefType
//*************************************************************************
TypeDefType::TypeDefType(TypeReader& typeReader,
			 	   		 const OString& typeName,
				   		 const TypeManager& typeMgr,
				   		 const TypeDependency& typeDependencies)
	: IdlType(typeReader, typeName, typeMgr, typeDependencies)
{
}

TypeDefType::~TypeDefType()
{

}

sal_Bool TypeDefType::dumpHFile(FileStream& o)
	throw( CannotDumpException )
{
	OString headerDefine(dumpHeaderDefine(o, "IDL"));
	o << "\n";

	dumpDefaultHIncludes(o);
	o << "\n";
	dumpDepIncludes(o, m_typeName, "idl");
	o << "\n";

	dumpNameSpace(o);

	o << "\ntypedef ";
	dumpType(o, m_reader.getSuperTypeName());
	o << " " << m_name << ";\n\n";

	dumpNameSpace(o, sal_False);

	o << "#endif /* "<< headerDefine << "*/" << "\n";

	return sal_True;
}


//*************************************************************************
// produceType
//*************************************************************************
sal_Bool produceType(const OString& typeName,
					 TypeManager& typeMgr,
					 TypeDependency& typeDependencies,
					 IdlOptions* pOptions)
	throw( CannotDumpException )
{
	if (typeDependencies.isGenerated(typeName))
		return sal_True;

	TypeReader reader(typeMgr.getTypeReader(typeName));

	if (!reader.isValid())
	{
		if (typeName.equals("/"))
			return sal_True;
		else
			return sal_False;
	}

	if( !checkTypeDependencies(typeMgr, typeDependencies, typeName))
		return sal_False;

	RTTypeClass typeClass = reader.getTypeClass();
	sal_Bool 	ret = sal_False;
	switch (typeClass)
	{
		case RT_TYPE_INTERFACE:
			{
				InterfaceType iType(reader, typeName, typeMgr, typeDependencies);
				ret = iType.dump(pOptions);
				if (ret) typeDependencies.setGenerated(typeName);
				ret = iType.dumpDependedTypes(pOptions);
			}
			break;
		case RT_TYPE_MODULE:
			{
				ModuleType mType(reader, typeName, typeMgr, typeDependencies);
				if (mType.hasConstants())
				{
					ret = mType.dump(pOptions);
					if (ret) typeDependencies.setGenerated(typeName);
//					ret = mType.dumpDependedTypes(pOptions);
				} else
				{
					typeDependencies.setGenerated(typeName);
					ret = sal_True;
				}
			}
			break;
		case RT_TYPE_STRUCT:
			{
				StructureType sType(reader, typeName, typeMgr, typeDependencies);
				ret = sType.dump(pOptions);
				if (ret) typeDependencies.setGenerated(typeName);
				ret = sType.dumpDependedTypes(pOptions);
			}
			break;
		case RT_TYPE_ENUM:
			{
				EnumType enType(reader, typeName, typeMgr, typeDependencies);
				ret = enType.dump(pOptions);
				if (ret) typeDependencies.setGenerated(typeName);
				ret = enType.dumpDependedTypes(pOptions);
			}
			break;
		case RT_TYPE_EXCEPTION:
			{
				ExceptionType eType(reader, typeName, typeMgr, typeDependencies);
				ret = eType.dump(pOptions);
				if (ret) typeDependencies.setGenerated(typeName);
				ret = eType.dumpDependedTypes(pOptions);
			}
			break;
		case RT_TYPE_TYPEDEF:
			{
				TypeDefType tdType(reader, typeName, typeMgr, typeDependencies);
				ret = tdType.dump(pOptions);
				if (ret) typeDependencies.setGenerated(typeName);
				ret = tdType.dumpDependedTypes(pOptions);
			}
			break;
		case RT_TYPE_CONSTANTS:
			{
				ConstantsType cType(reader, typeName, typeMgr, typeDependencies);
				if (cType.hasConstants())
				{
					ret = cType.dump(pOptions);
					if (ret) typeDependencies.setGenerated(typeName);
//					ret = cType.dumpDependedTypes(pOptions);
				} else
				{
					typeDependencies.setGenerated(typeName);
					ret = sal_True;
				}
			}
			break;
		case RT_TYPE_SERVICE:
		case RT_TYPE_OBJECT:
			ret = sal_True;
			break;
	}

	return ret;
}

//*************************************************************************
// scopedName
//*************************************************************************
OString scopedName(const OString& scope, const OString& type,
				   sal_Bool bNoNameSpace)
{
    sal_Int32 nPos = type.lastIndexOf( '/' );
	if (nPos == -1)
		return type;

	if (bNoNameSpace)
		return type.copy(nPos+1);

	OStringBuffer tmpBuf(type.getLength()*2);
    nPos = 0;
    do
	{
		tmpBuf.append("::");
		tmpBuf.append(type.getToken(0, '/', nPos));
	} while( nPos != -1 );

	return tmpBuf.makeStringAndClear();
}

//*************************************************************************
// shortScopedName
//*************************************************************************
OString scope(const OString& scope, const OString& type )
{
    sal_Int32 nPos = type.lastIndexOf( '/' );
    if( nPos == -1 )
        return OString();

	// scoped name only if the namespace is not equal
	if (scope.lastIndexOf('/') > 0)
	{
		OString tmpScp(scope.copy(0, scope.lastIndexOf('/')));
		OString tmpScp2(type.copy(0, nPos));

		if (tmpScp == tmpScp2)
			return OString();
	}

    OString aScope( type.copy( 0, nPos ) );
	OStringBuffer tmpBuf(aScope.getLength()*2);

    nPos = 0;
    do
	{
		tmpBuf.append("::");
		tmpBuf.append(aScope.getToken(0, '/', nPos));
	} while( nPos != -1 );

	return tmpBuf.makeStringAndClear();
}


