/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/

package complex.storages;

import com.sun.star.uno.XInterface;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;

import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

import com.sun.star.embed.*;

import share.LogWriter;
import complex.storages.TestHelper;
import complex.storages.StorageTest;

public class Test18 implements StorageTest {

	XMultiServiceFactory m_xMSF;
	XSingleServiceFactory m_xStorageFactory;
	TestHelper m_aTestHelper;

	public Test18( XMultiServiceFactory xMSF, XSingleServiceFactory xStorageFactory, LogWriter aLogWriter )
	{
		m_xMSF = xMSF;
		m_xStorageFactory = xStorageFactory;
		m_aTestHelper = new TestHelper( aLogWriter, "Test18: " );
	}

    public boolean test()
	{
		try
		{
            // test the default value of Compressed property
			String sTempFileURL = m_aTestHelper.CreateTempFile( m_xMSF );
			if ( sTempFileURL == null || sTempFileURL == "" )
			{
				m_aTestHelper.Error( "No valid temporary file was created!" );
				return false;
			}
		
			// create temporary storage based on arbitrary medium
			// after such a storage is closed it is lost
			Object oTempStorage = m_xStorageFactory.createInstance();
			XStorage xTempStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
			if ( xTempStorage == null )
			{
				m_aTestHelper.Error( "Can't create temporary storage representation!" );
				return false;
			}

			// open a new substorage
			XStorage xTempSubStorage = m_aTestHelper.openSubStorage( xTempStorage,
																		"SubStorage1",
																		ElementModes.WRITE );
			if ( xTempSubStorage == null )
			{
				m_aTestHelper.Error( "Can't create substorage!" );
				return false;
			}
			
			byte pBytes1[] = { 1, 1, 1, 1, 1 };

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream1", "image/jpeg", pBytes1 ) )
				return false;

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream2", "image/png", pBytes1 ) )
				return false;
	
			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream3", "image/gif", pBytes1 ) )
				return false;

			// open a new substream, set "MediaType" and "Compressed" properties to it and write some bytes
			if ( !m_aTestHelper.WriteBytesToSubstreamDefaultCompressed( xTempSubStorage, "SubStream4", "MediaType1", pBytes1 ) )
				return false;

			// set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
			if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempStorage,
															"MediaType3",
															true,
															ElementModes.WRITE ) )
				return false;

			// set "MediaType" property for storages and check that "IsRoot" and "OpenMode" properties are set correctly
			if ( !m_aTestHelper.setStorageTypeAndCheckProps( xTempSubStorage,
															"MediaType4",
															false,
															ElementModes.WRITE ) )
				return false;
	
			// create temporary storage based on a previously created temporary file
			Object pArgs[] = new Object[2];
			pArgs[0] = (Object) sTempFileURL;
			pArgs[1] = new Integer( ElementModes.WRITE );

			Object oTempFileStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
			XStorage xTempFileStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oTempFileStorage );
			if ( xTempFileStorage == null )
			{
				m_aTestHelper.Error( "Can't create storage based on temporary file!" );
				return false;
			}

			// copy xTempStorage to xTempFileStorage
			// xTempFileStorage will be automatically commited
			if ( !m_aTestHelper.copyStorage( xTempStorage, xTempFileStorage ) )
				return false;

			// dispose used storages to free resources
			if ( !m_aTestHelper.disposeStorage( xTempStorage ) || !m_aTestHelper.disposeStorage( xTempFileStorage ) )
				return false;

			// ================================================
			// now check all the written and copied information
			// ================================================

			// the temporary file must not be locked any more after storage disposing
			pArgs[1] = new Integer( ElementModes.WRITE );
			Object oResultStorage = m_xStorageFactory.createInstanceWithArguments( pArgs );
			XStorage xResultStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oResultStorage );
			if ( xResultStorage == null )
			{
				m_aTestHelper.Error( "Can't reopen storage based on temporary file!" );
				return false;
			}

			if ( !m_aTestHelper.checkStorageProperties( xResultStorage, "MediaType3", true, ElementModes.WRITE ) )
				return false;

			// open existing substorage
			XStorage xResultSubStorage = m_aTestHelper.openSubStorage( xResultStorage,
																		"SubStorage1",
																		ElementModes.READ );
			if ( xResultSubStorage == null )
			{
				m_aTestHelper.Error( "Can't open existing substorage!" );
				return false;
			}
	
			if ( !m_aTestHelper.checkStorageProperties( xResultSubStorage, "MediaType4", false, ElementModes.READ ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream1", "image/jpeg", false, pBytes1 ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream2", "image/png", false, pBytes1 ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream3", "image/gif", false, pBytes1 ) )
				return false;

			if ( !m_aTestHelper.checkStream( xResultSubStorage, "SubStream4", "MediaType1", true, pBytes1 ) )
				return false;

			// dispose used storages to free resources
			if ( !m_aTestHelper.disposeStorage( xResultStorage ) )
				return false;

			return true;
		}
		catch( Exception e )
		{
			m_aTestHelper.Error( "Exception: " + e );
			return false;
		}
    } 

}

