/******************************************************************************* * Copyright 2012 University of Southern California * * 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. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ /** * */ package edu.isi.karma.view.tabledata; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.json.JSONException; import org.json.JSONWriter; import edu.isi.karma.view.Stroke; import edu.isi.karma.view.Stroke.StrokeStyle; import edu.isi.karma.view.tabledata.VDCell.Position; /** * @author szekely * */ public class VDCellStrokes { public class StrokeIterator implements Iterator<Stroke> { private final Position position; private int index = 0; private int increment = 1; private int limit; StrokeIterator(Position position) { this.position = position; this.limit = strokes[position.ordinal()].length - 1; if (position == Position.right || position == Position.bottom) { this.index = strokes[position.ordinal()].length - 2; this.increment = -1; limit = 0; } } public boolean hasNext() { return increment == 1 ? index != limit : index >= limit; } public Stroke next() { Stroke result = strokes[position.ordinal()][index]; index += increment; return result; } public void remove() { throw new Error("Cannot remove!"); } } private int[] minDepth = new int[4]; /** * First dimension is Position.ordinal(), the second is the stroke depth * minus minDepth. */ private Stroke[][] strokes = new Stroke[4][]; private final int cellDepth; public static VDCellStrokes create(int cellDepth, VDVerticalSeparator vdVS, int numTop, int minTop, int numBottom, int minBottom) { int numLeft = vdVS.getLeftStrokes().size(); int minLeft = vdVS.getMinDepth(Position.left); int numRight = vdVS.getRightStrokes().size(); int minRight = vdVS.getMinDepth(Position.right); return new VDCellStrokes(cellDepth, numLeft, numRight, numTop, numBottom, minLeft, minRight, minTop, minBottom); } VDCellStrokes(int cellDepth, int numLeft, int numRight, int numTop, int numBottom, int minLeft, int minRight, int minTop, int minBottom) { this.cellDepth = cellDepth; minDepth[Position.left.ordinal()] = minLeft; minDepth[Position.right.ordinal()] = minRight; minDepth[Position.top.ordinal()] = minTop; minDepth[Position.bottom.ordinal()] = minBottom; int[] numStrokes = new int[4]; numStrokes[Position.left.ordinal()] = numLeft; numStrokes[Position.right.ordinal()] = numRight; numStrokes[Position.top.ordinal()] = numTop; numStrokes[Position.bottom.ordinal()] = numBottom; for (Position pos : Position.values()) { strokes[pos.ordinal()] = new Stroke[numStrokes[pos.ordinal()]]; } } int getNumStrokes(Position position) { return strokes[position.ordinal()].length - 1; } StrokeIterator iterator(Position position) { return new StrokeIterator(position); } private void addStroke(Stroke stroke, Position position) { strokes[position.ordinal()][stroke.getDepth() - minDepth[position.ordinal()]] = stroke; } private void addStrokes(List<Stroke> strokes, Position position) { for (Stroke s : strokes) { addStroke(s, position); } } void populateFromVDCell(VDVerticalSeparator vdVerticalSeparator, VDCell c) { // Add the vertical strokes as defaults, so we get the correct colors // and no lines. addStrokes(vdVerticalSeparator.getLeftStrokes(), Position.left); addStrokes(vdVerticalSeparator.getRightStrokes(), Position.right); // Now copy all the strokes from the cell. addStrokes(c.getLeftStrokes(), Position.left); addStrokes(c.getRightStrokes(), Position.right); addStrokes(c.getTopStrokes(), Position.top); addStrokes(c.getBottomStrokes(), Position.bottom); } void setDefault(Stroke stroke, Set<Stroke> defaultStrokes) { for (int i = 0; i < 4; i++) { for (int j = 0; j < strokes[i].length; j++) { Stroke s = strokes[i][j]; if (j + minDepth[i] + cellDepth >= stroke.getDepth()) { if (s == null || defaultStrokes.contains(s)) { strokes[i][j] = new Stroke(StrokeStyle.none, stroke.getHTableId(), j + minDepth[i] + cellDepth); defaultStrokes.add(strokes[i][j]); } } } } } public String getHTableId(int depth) { for (int i = 0; i < 4; i++) { int index = depth - minDepth[i]; if (index >= 0 && index < strokes[i].length) { return strokes[i][index].getHTableId(); } } return null; } Stroke getStroke(Position position, int depth) { int index = depth - minDepth[position.ordinal()]; if (index >= 0 && index < strokes[position.ordinal()].length) { return strokes[position.ordinal()][index]; } else { if (depth > 0) { return getStroke(position, depth - 1); } return null; } } Stroke getStrokeByIndex(Position position, int index) { if (index >= 0 && index < strokes[position.ordinal()].length) { return strokes[position.ordinal()][index]; } else { return new Stroke(StrokeStyle.none, "" + position.name() + "/" + index, index + minDepth[position.ordinal()]); } } int ordinalToIndex(Position position, int ordinal) { int index = ordinal - 1; if (position == Position.right || position == Position.bottom) { index = strokes[position.ordinal()].length - ordinal - 1; } return index; } // int getDistanceFromCell(Position position, int ordinal) { // if (position == Position.left || position == Position.top) { // return strokes[position.ordinal()].length - ordinal; // } else { // return ordinal; // } // } // Stroke getMaxStroke(Position position) { // Stroke[] x = strokes[position.ordinal()]; // return x[x.length - 1]; // } List<Stroke> getList(Position position) { List<Stroke> result = new LinkedList<Stroke>(); for (int i = 0; i < strokes[position.ordinal()].length; i++) { Stroke s = strokes[position.ordinal()][i]; if (s == null) { s = new Stroke(-1); } result.add(s); } return result; } void populateStrokeStyles(StrokeStyles strokeStyles) { for (Position p : Position.values()) { strokeStyles.setStrokeStyle(p, strokes[p.ordinal()][strokes[p .ordinal()].length - 1].getStyle()); } } /***************************************************************** * * Debugging Support * *****************************************************************/ JSONWriter prettyPrintJson(JSONWriter jw, Set<Stroke> defaultStrokes) throws JSONException { jw.object() // .key("_D") .value(cellDepth) // .key("_minT") .value(minDepth[Position.top.ordinal()]) // .key("_minB") .value(minDepth[Position.bottom.ordinal()]) // .key("_minL") .value(minDepth[Position.left.ordinal()]) // .key("_minR") .value(minDepth[Position.right.ordinal()]) // .key("left_S") .value(Stroke.toString(getList(Position.left), defaultStrokes)) // .key("right_S") .value(Stroke.toString(getList(Position.right), defaultStrokes)) // .key("top_S") .value(Stroke.toString(getList(Position.top), defaultStrokes)) // .key("bottom_S") .value(Stroke .toString(getList(Position.bottom), defaultStrokes))// .endObject(); return jw; } }