/*
 *******************************************************************************
 * Copyright (C) 2002-2004, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import com.ibm.icu.dev.test.TestFmwk;

import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.CompactByteArray;
import com.ibm.icu.util.CompactCharArray;

/**
 * @since release 2.2
 */
public final class CompactArrayTest extends TestFmwk 
{ 
    public static void main(String[] args) throws Exception
    {
        new CompactArrayTest().run(args);
    }
    
    public void TestByteArrayCoverage() {
	CompactByteArray cba = new CompactByteArray();
	cba.setElementAt((char)0x5, (byte)0xdf);
	cba.setElementAt((char)0x105, (byte)0xdf);
	cba.setElementAt((char)0x205, (byte)0xdf);
	cba.setElementAt((char)0x305, (byte)0xdf);
	CompactByteArray cba2 = new CompactByteArray((byte)0xdf);
	if (cba.equals(cba2)) {
	    errln("unequal byte arrays compare equal");
	}
	CompactByteArray cba3 = (CompactByteArray)cba.clone();

	logln("equals null: " + cba.equals(null));
	logln("equals self: " + cba.equals(cba));
	logln("equals clone: " + cba.equals(cba3));
	logln("equals bogus: " + cba.equals(new Object()));
	logln("hash: " + cba.hashCode());

	cba.compact(true);
	cba.compact(true);

	char[] xa = cba.getIndexArray();
	byte[] va = cba.getValueArray();
	CompactByteArray cba4 = new CompactByteArray(xa, va);

	String xs = Utility.arrayToRLEString(xa);
	String vs = Utility.arrayToRLEString(va);
	CompactByteArray cba5 = new CompactByteArray(xs, vs);

	logln("equals: " + cba4.equals(cba5));
	logln("equals: " + cba.equals(cba4));
    
  	cba4.compact(false);
	logln("equals: " + cba4.equals(cba5));

	cba5.compact(true);
	logln("equals: " + cba4.equals(cba5));

	cba.setElementAt((char)0x405, (byte)0xdf); // force expand
	logln("modified equals clone: " + cba.equals(cba3));

	cba3.setElementAt((char)0x405, (byte)0xdf); // equivalent modification
	logln("modified equals modified clone: " + cba.equals(cba3));

	cba3.setElementAt((char)0x405, (byte)0xee); // different modification
	logln("different mod equals: " + cba.equals(cba3));

	cba.compact();
	CompactByteArray cba6 = (CompactByteArray)cba.clone();
	logln("cloned compact equals: " + cba.equals(cba6));

	cba6.setElementAt((char)0x405, (byte)0xee);
	logln("modified clone: " + cba3.equals(cba6));

	cba6.setElementAt((char)0x100, (char)0x104, (byte)0xfe);
	for (int i = 0x100; i < 0x105; ++i) {
	    cba3.setElementAt((char)i, (byte)0xfe);
	}
	logln("double modified: " + cba3.equals(cba6));
    }

    public void TestCharArrayCoverage() {
	// v1.8 fails with extensive compaction, so set to false
	final boolean EXTENSIVE = false;

	CompactCharArray cca = new CompactCharArray();
	cca.setElementAt((char)0x5, (char)0xdf);
	cca.setElementAt((char)0x105, (char)0xdf);
	cca.setElementAt((char)0x205, (char)0xdf);
	cca.setElementAt((char)0x305, (char)0xdf);
	CompactCharArray cca2 = new CompactCharArray((char)0xdf);
	if (cca.equals(cca2)) {
	    errln("unequal char arrays compare equal");
	}
	CompactCharArray cca3 = (CompactCharArray)cca.clone();

	logln("equals null: " + cca.equals(null));
	logln("equals self: " + cca.equals(cca));
	logln("equals clone: " + cca.equals(cca3));
	logln("equals bogus: " + cca.equals(new Object()));
	logln("hash: " + cca.hashCode());

	cca.compact(EXTENSIVE);
	cca.compact(EXTENSIVE);

	char[] xa = cca.getIndexArray();
	char[] va = cca.getValueArray();
	CompactCharArray cca4 = new CompactCharArray(xa, va);

	String xs = Utility.arrayToRLEString(xa);
	String vs = Utility.arrayToRLEString(va);
	CompactCharArray cca5 = new CompactCharArray(xs, vs);

	logln("equals: " + cca4.equals(cca5));
	logln("equals: " + cca.equals(cca4));

	cca4.compact(false);
	logln("equals: " + cca4.equals(cca5));

	cca5.compact(EXTENSIVE);
	logln("equals: " + cca4.equals(cca5));

	cca.setElementAt((char)0x405, (char)0xdf); // force expand
	logln("modified equals clone: " + cca.equals(cca3));

	cca3.setElementAt((char)0x405, (char)0xdf); // equivalent modification
	logln("modified equals modified clone: " + cca.equals(cca3));

	cca3.setElementAt((char)0x405, (char)0xee); // different modification
	logln("different mod equals: " + cca.equals(cca3));
    
    // after setElementAt isCompact is set to false
    cca3.compact(true);
    logln("different mod equals: " + cca.equals(cca3));
    
    cca3.setElementAt((char)0x405, (char)0xee); // different modification
    logln("different mod equals: " + cca.equals(cca3));
	    // after setElementAt isCompact is set to false
    cca3.compact();
    logln("different mod equals: " + cca.equals(cca3));
    
    // v1.8 fails with extensive compaction, and defaults extensive, so don't compact
	// cca.compact();
	CompactCharArray cca6 = (CompactCharArray)cca.clone();
	logln("cloned compact equals: " + cca.equals(cca6));

	cca6.setElementAt((char)0x405, (char)0xee);
	logln("modified clone: " + cca3.equals(cca6));

	cca6.setElementAt((char)0x100, (char)0x104, (char)0xfe);
	for (int i = 0x100; i < 0x105; ++i) {
	    cca3.setElementAt((char)i, (char)0xfe);
	}
	logln("double modified: " + cca3.equals(cca6));
    }
}
