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

#pragma warning(disable: 4917)
#include <windows.h>
#include <comdef.h>
#include <tchar.h>
#include <atlbase.h>
#include<atlcom.h>
#include <stdio.h>
#include <com/sun/star/bridge/ModelDependent.hpp>
#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <oletest/XCallback.hpp>
#include <rtl/process.h>
#include <com/sun/star/uno/Reference.h>
#include <cppuhelper/servicefactory.hxx>
#include <rtl/string.h>



using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace com::sun::star::script;
using namespace com::sun::star::bridge;
using namespace com::sun::star::bridge::ModelDependent;
using namespace cppu;
using namespace rtl;
HRESULT doTest();
bool incrementMultidimensionalIndex(
    sal_Int32 dimensions,
    const sal_Int32 * parDimensionLengths,
    sal_Int32 * parMultidimensionalIndex);

int __cdecl _tmain( int /*argc*/, _TCHAR * /*argv[]*/ )
{
	HRESULT hr;
	if( FAILED( hr=CoInitialize(NULL)))
	{
		_tprintf(_T("CoInitialize failed \n"));
		return -1;
	}


	if( FAILED(hr=doTest()))
	{
		_com_error err( hr);
		const TCHAR * errMsg= err.ErrorMessage();
		MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR);
	}

	CoUninitialize();
	return 0;
}




HRESULT doTest()
{
	HRESULT hr= S_OK;
	long j = 0;
	SAFEARRAY* par;
	CComDispatchDriver disp;
	CComVariant result;
	CComVariant param1;
	CComPtr<IUnknown> spUnkFactory;
	if( SUCCEEDED( spUnkFactory.CoCreateInstance(L"com.sun.star.ServiceManager")))
	{
		disp= spUnkFactory;
		param1= L"oletest.OleTest";
		disp.Invoke1( L"createInstance", &param1, &result);

		disp= result.pdispVal;

		// disp contains now oletest.OleTest

		// one dimensional array
		par= SafeArrayCreateVector( VT_UI1, 0, 5);
		unsigned char arbyte[]= { 1,2,3,4,5};
		for(long i= 0; i < 5;i++)
			hr=	SafeArrayPutElement( par, &i, &arbyte[i]);

		result.Clear();
		param1.vt= VT_ARRAY| VT_UI1;
		param1.byref= par;
		disp.Invoke1(L"methodByte", &param1, &result);
		SafeArrayDestroy( par);


		// two dimensional array
		SAFEARRAYBOUND bounds[2];
		// least significant dimension first, Dimension 1
		bounds[0].cElements= 3;
		bounds[0].lLbound= 0;
		// Dimension 2
		bounds[1].cElements= 2;
		bounds[1].lLbound= 0;
		par= SafeArrayCreate( VT_I4, 2, bounds );

		long uBound1;
		long uBound2;
		hr= SafeArrayGetUBound( par, 1, &uBound1);
		hr= SafeArrayGetUBound( par, 2, &uBound2);

		long index2[2];
		memset( index2, 0, 2 * sizeof( long) );
		long dimLengths[]={3,2};

		long data;
		do
		{
			data= index2[1] * 3 + index2[0] +1;
			hr= SafeArrayPutElement( par, index2, &data);
		}while( incrementMultidimensionalIndex( 2, dimLengths, index2) );

		long* pdata;
		long (*dataL)[2][3];
		hr= SafeArrayAccessData( par, (void**)&pdata);
		dataL= (long(*)[2][3])pdata;

		for (long i= 0; i < 2; i ++)
		{
			for(long j= 0; j < 3; j++)
				data= (*dataL)[i][j];
		}
		hr= SafeArrayUnaccessData(par);

		result.Clear();
		param1.vt= VT_ARRAY | VT_I4;
		param1.byref= par;
		disp.Invoke1(L"methodSequence", &param1, &result);

		SAFEARRAY* arRet= result.parray;

		for(long i= 0; i < 2 ; i++)
		{
			CComVariant varx;
			varx.Clear();
			hr= SafeArrayGetElement( arRet, &i, &varx);
			SAFEARRAY* ari= varx.parray;

			for( j= 0; j < 3; j++)
			{
				CComVariant varj;
				varj.Clear();
				hr= SafeArrayGetElement( ari, &j, &varj);
			}



		}
		SafeArrayDestroy( par);
	}

	return hr;
}

// left index is least significant
bool incrementMultidimensionalIndex(
    sal_Int32 dimensions,
    const sal_Int32 * parDimensionLengths,
	sal_Int32 * parMultidimensionalIndex)
{
	if( dimensions < 1)
		return sal_False;

	bool ret= sal_True;
	bool carry= sal_True; // to get into the while loop

	sal_Int32 currentDimension= 0; //most significant is 1
	while( carry)
	{
		parMultidimensionalIndex[ currentDimension ]++;
		// if carryover, set index to 0 and handle carry on a level above
		if( parMultidimensionalIndex[ currentDimension] > (parDimensionLengths[ currentDimension] - 1))
			parMultidimensionalIndex[ currentDimension]= 0;
		else
			carry= sal_False;

		currentDimension ++;
		// if dimensions drops below 1 and carry is set than then all indices are 0 again
		// this is signalled by returning sal_False
		if( currentDimension > dimensions - 1 && carry)
		{
			carry= sal_False;
			ret= sal_False;
		}
	}
	return ret;
}
