/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed 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 android.text;

import junit.framework.TestCase;

/**
 * PackedIntVectorTest tests the features of android.util.PackedIntVector.
 */
public class PackedIntVectorTest extends TestCase {
 
    public void testBasic() throws Exception {
        for (int width = 0; width < 10; width++) {
            PackedIntVector p = new PackedIntVector(width);
            int[] ins = new int[width];

            for (int height = width * 2; height < width * 4; height++) {
                assertEquals(p.width(), width);

                // Test adding rows.

                for (int i = 0; i < height; i++) {
                    int at;

                    if (i % 2 == 0) {
                        at = i;
                    } else {
                        at = p.size() - i;
                    }

                    for (int j = 0; j < width; j++) {
                        ins[j] = i + j;
                    }

                    if (i == height / 2) {
                        p.insertAt(at, null);
                    } else {
                        p.insertAt(at, ins);
                    }

                    assertEquals(p.size(), i + 1);

                    for (int j = 0; j < width; j++) {
                        if (i == height / 2) {
                            assertEquals(0, p.getValue(at, j));
                        } else {
                            assertEquals(p.getValue(at, j), i + j);
                        }
                    }
                }

                // Test setting values.

                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        p.setValue(i, j, i * j);

                        assertEquals(p.getValue(i, j), i * j);
                    }
                }

                // Test offsetting values.

                for (int j = 0; j < width; j++) {
                    p.adjustValuesBelow(j * 2, j, j + 27);
                }

                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        int expect = i * j;

                        if (i >= j * 2) {
                            expect += j + 27;
                        }

                        assertEquals(p.getValue(i, j), expect);
                    }
                }

                for (int j = 0; j < width; j++) {
                    p.adjustValuesBelow(j, j, j * j + 14);
                }

                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        int expect = i * j;

                        if (i >= j * 2) {
                            expect += j + 27;
                        }
                        if (i >= j) {
                            expect += j * j + 14;
                        }

                        assertEquals(p.getValue(i, j), expect);
                    }
                }

                // Test undoing offsets.

                for (int j = 0; j < width; j++) {
                    p.adjustValuesBelow(j * 2, j, -(j + 27));
                    p.adjustValuesBelow(j, j, -(j * j + 14));
                }

                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        assertEquals(p.getValue(i, j), i * j);
                    }
                }

                // Test deleting rows.

                while (p.size() > 0) {
                    int osize = p.size();
                    int del = osize / 3;

                    if (del == 0) {
                        del = 1;
                    }

                    int at = (osize - del) / 2;
                    p.deleteAt(at, del);

                    assertEquals(p.size(), osize - del);

                    for (int i = 0; i < at; i++) {
                        for (int j = 0; j < width; j++) {
                            assertEquals(p.getValue(i, j), i * j);
                        }
                    }

                    for (int i = at; i < p.size(); i++) {
                        for (int j = 0; j < width; j++) {
                            assertEquals(p.getValue(i, j), (i + height - p.size()) * j);
                        }
                    }
                }

                assertEquals(0, p.size());
            }
        }
    }
}
