/**************************************************************
 *
 * 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"
// cpptest.cpp : Defines the entry point for the console application.
//

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma warning(disable: 4917)
#include <comdef.h>
#include <tchar.h>
#include<atlbase.h>
#include<atlcom.h>

HRESULT doTest();

int main(int /*argc*/, char** /*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;
	CComPtr<IUnknown> spUnkMgr;


	if( FAILED(hr= spUnkMgr.CoCreateInstance(L"com.sun.star.ServiceManager")))
		return hr;

	IDispatchPtr starManager;
    //    var starManager=new ActiveXObject("com.sun.star.ServiceManager");
	if (FAILED(hr= starManager.CreateInstance(_T("com.sun.star.ServiceManager"))))
    {
        fprintf(stderr, "creating ServiceManager failed\n");
        return hr;
    }
    //    var starDesktop=starManager.createInstance("com.sun.star.frame.Desktop");
	_variant_t varP1(L"com.sun.star.frame.Desktop");
	_variant_t varRet;
	CComDispatchDriver dispMgr(starManager);
	if (FAILED(hr=	dispMgr.Invoke1(L"createInstance", &varP1, &varRet)))
    {
        fprintf(stderr,"createInstance of Desktop failed\n");
        return hr;
    }
	CComDispatchDriver dispDesk(varRet.pdispVal);
	varP1.Clear();
	varRet.Clear();
	//    var bOK=new Boolean(true);

    //    var noArgs=new Array();
    //    var oDoc=starDesktop.loadComponentFromURL("private:factory/swriter", "Test", 40, noArgs);
	IDispatchPtr oDoc;
	SAFEARRAY* ar= SafeArrayCreateVector(VT_DISPATCH, 0, 0);
	_variant_t args[4];
	args[3]= _variant_t(L"private:factory/swriter");
	args[2]= _variant_t(L"Test");
	args[1]= _variant_t((long) 40);
	args[0].vt= VT_ARRAY | VT_DISPATCH;
	args[0].parray= ar;
	if (FAILED(hr= dispDesk.InvokeN(L"loadComponentFromURL", args, 4, &varRet)))
    {
        fprintf(stderr,"loadComponentFromURL failed\n");
        return hr;
    }
	CComDispatchDriver dispDoc(varRet.pdispVal);
	varRet.Clear();
	return S_OK;

}
