/*
* Copyright 2015 Skynav, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY SKYNAV, INC. AND ITS CONTRIBUTORS “AS IS” AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SKYNAV, INC. OR ITS CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.skynav.ttv.verifier.util;
import com.skynav.ttv.model.value.Length;
import com.skynav.ttv.model.value.impl.LengthImpl;
import com.skynav.ttv.util.Location;
import com.skynav.ttv.verifier.VerifierContext;
public class Positions {
private static final Length PCT_0 = new LengthImpl(0, Length.Unit.Percentage);
private static final Length PCT_50 = new LengthImpl(50, Length.Unit.Percentage);
private static final Length PCT_100 = new LengthImpl(100, Length.Unit.Percentage);
private static final Object[] TREATMENTS = new Object[] { NegativeTreatment.Allow };
public static boolean isPosition(String[] components, Location location, VerifierContext context, Length[] outputLengths) {
if (is1ComponentPosition(components, location, context, outputLengths))
return true;
else if (is2ComponentPosition(components, location, context, outputLengths))
return true;
else if (is3ComponentPosition(components, location, context, outputLengths))
return true;
else if (is4ComponentPosition(components, location, context, outputLengths))
return true;
else
return false;
}
private static boolean is1ComponentPosition(String[] components, Location location, VerifierContext context, Length[] outputLengths) {
if (components.length == 1) {
Length[] lengths = new Length[2];
if (isOffsetPositionHorizontal(components, 0, location, context, lengths)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = lengths[0];
outputLengths[1] = PCT_50;
}
return true;
} else if (isOffsetPositionVertical(components, 0, location, context, lengths)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = PCT_50;
outputLengths[1] = lengths[1];
}
return true;
}
}
return false;
}
private static boolean is2ComponentPosition(String[] components, Location location, VerifierContext context, Length[] outputLengths) {
if (components.length == 2) {
Length[] lengths = new Length[4];
if (isOffsetPositionHorizontal(components, 0, location, context, lengths) && isOffsetPositionVertical(components, 1, location, context, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
}
return false;
}
private static boolean is3ComponentPosition(String[] components, Location location, VerifierContext context, Length[] outputLengths) {
if (components.length == 3) {
Length[] lengths;
lengths = new Length[4];
if (isPositionKeywordHorizontal(components, 0, lengths) && isEdgeOffsetVertical(components, 1, location, context, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
lengths = new Length[4];
if (isPositionKeywordVertical(components, 0, lengths) && isEdgeOffsetHorizontal(components, 1, location, context, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
lengths = new Length[4];
if (isEdgeOffsetHorizontal(components, 0, location, context, lengths) && isPositionKeywordVertical(components, 2, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
lengths = new Length[4];
if (isEdgeOffsetVertical(components, 0, location, context, lengths) && isPositionKeywordHorizontal(components, 2, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
}
return false;
}
private static boolean is4ComponentPosition(String[] components, Location location, VerifierContext context, Length[] outputLengths) {
if (components.length == 4) {
Length[] lengths;
lengths = new Length[4];
if (isEdgeOffsetHorizontal(components, 0, location, context, lengths) && isEdgeOffsetVertical(components, 2, location, context, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
lengths = new Length[4];
if (isEdgeOffsetVertical(components, 0, location, context, lengths) && isEdgeOffsetHorizontal(components, 2, location, context, lengths))
return componentPositionContinuation(lengths, outputLengths, true);
}
return false;
}
private static boolean componentPositionContinuation(Length[] lengths, Length[] outputLengths, boolean rv) {
if (outputLengths != null) {
assert lengths != null;
assert lengths.length >= 4;
assert outputLengths.length >= 4;
for (int i = 0, n = 4; i < n; ++i)
outputLengths[i] = lengths[i];
}
return rv;
}
private static boolean isOffsetPositionHorizontal(String[] components, int index, Location location, VerifierContext context, Length[] outputLengths) {
return isOffsetPositionHorizontal(components[index], location, context, outputLengths);
}
private static boolean isOffsetPositionVertical(String[] components, int index, Location location, VerifierContext context, Length[] outputLengths) {
return isOffsetPositionVertical(components[index], location, context, outputLengths);
}
private static boolean isEdgeOffsetHorizontal(String[] components, int index, Location location, VerifierContext context, Length[] outputLengths) {
if ((index + 2) <= components.length)
return isEdgeOffsetHorizontal(components[index + 0], components[index + 1], location, context, outputLengths);
else
return false;
}
private static boolean isEdgeOffsetVertical(String[] components, int index, Location location, VerifierContext context, Length[] outputLengths) {
if ((index + 2) <= components.length)
return isEdgeOffsetVertical(components[index + 0], components[index + 1], location, context, outputLengths);
else
return false;
}
private static boolean isPositionKeywordHorizontal(String[] components, int index, Length[] outputLengths) {
return isPositionKeywordHorizontal(components[index], outputLengths);
}
private static boolean isPositionKeywordVertical(String[] components, int index, Length[] outputLengths) {
return isPositionKeywordVertical(components[index], outputLengths);
}
private static boolean isOffsetPositionHorizontal(String component, Location location, VerifierContext context, Length[] outputLengths) {
if (isPositionKeywordHorizontal(component, outputLengths))
return true;
else {
Length[] length = new Length[1];
if (Lengths.isLength(component, location, context, TREATMENTS, length)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = length[0];
}
return true;
} else
return false;
}
}
private static boolean isPositionKeywordHorizontal(String component, Length[] outputLengths) {
if (isCenterKeyword(component)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = PCT_50;
}
return true;
} else if (isEdgeKeywordHorizontal(component, outputLengths))
return true;
else
return false;
}
private static boolean isEdgeOffsetHorizontal(String c1, String c2, Location location, VerifierContext context, Length[] outputLengths) {
Length[] lengths = new Length[2];
if (isEdgeKeywordHorizontal(c1, lengths)) {
Length[] offset = new Length[1];
if (Lengths.isLength(c2, location, context, TREATMENTS, offset)) {
if (outputLengths != null) {
assert outputLengths.length >= 4;
outputLengths[0] = lengths[0];
outputLengths[2] = c1.equals("left") ? offset[0].negate() : offset[0];
}
return true;
}
}
return false;
}
private static boolean isEdgeKeywordHorizontal(String component, Length[] outputLengths) {
if (component.equals("left")) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = PCT_0;
}
return true;
} else if (component.equals("right")) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[0] = PCT_100;
}
return true;
} else
return false;
}
private static boolean isOffsetPositionVertical(String component, Location location, VerifierContext context, Length[] outputLengths) {
if (isPositionKeywordVertical(component, outputLengths))
return true;
else {
Length[] length = new Length[1];
if (Lengths.isLength(component, location, context, TREATMENTS, length)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[1] = length[0];
}
return true;
} else
return false;
}
}
private static boolean isPositionKeywordVertical(String component, Length[] outputLengths) {
if (isCenterKeyword(component)) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[1] = PCT_50;
}
return true;
} else if (isEdgeKeywordVertical(component, outputLengths))
return true;
else
return false;
}
private static boolean isEdgeOffsetVertical(String c1, String c2, Location location, VerifierContext context, Length[] outputLengths) {
Length[] lengths = new Length[2];
if (isEdgeKeywordVertical(c1, lengths)) {
Length[] offset = new Length[1];
if (Lengths.isLength(c2, location, context, TREATMENTS, offset)) {
if (outputLengths != null) {
assert outputLengths.length >= 4;
outputLengths[1] = lengths[1];
outputLengths[3] = c1.equals("top") ? offset[0].negate() : offset[0];
}
return true;
}
}
return false;
}
private static boolean isEdgeKeywordVertical(String component, Length[] outputLengths) {
if (component.equals("top")) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[1] = PCT_0;
}
return true;
} else if (component.equals("bottom")) {
if (outputLengths != null) {
assert outputLengths.length >= 2;
outputLengths[1] = PCT_100;
}
return true;
} else
return false;
}
private static boolean isCenterKeyword(String component) {
return component.equals("center");
}
}