/*
 * Copyright 2017-present Open Networking Laboratory
 *
 * 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 org.onosproject.ui.topo;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Represents a "node location" on a UI layout.
 */
public final class LayoutLocation {
    private static final double ZERO_THRESHOLD = Double.MIN_VALUE * 2.0;

    /**
     * Designates the type of location; either geographic or logical grid.
     */
    public enum Type {
        GEO, GRID
    }

    private final String id;
    private final double latOrY;
    private final double longOrX;
    private final Type locType;

    private LayoutLocation(String id, Type locType, double latOrY, double longOrX) {
        this.id = id;
        this.latOrY = latOrY;
        this.longOrX = longOrX;
        this.locType = locType;
    }


    private boolean doubleIsZero(double value) {
        return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD;
    }

    /**
     * Returns true if the coordinates indicate the origin (0, 0) of the
     * coordinate system; false otherwise.
     *
     * @return true if geo-coordinates are set; false otherwise
     */
    public boolean isOrigin() {
        return doubleIsZero(latOrY) && doubleIsZero(longOrX);
    }

    /**
     * Returns the identifier associated with this location.
     *
     * @return the identifier
     */
    public String id() {
        return id;
    }

    /**
     * Returns the latitude (geo) or y-coord (grid) data value.
     *
     * @return geo latitude or grid y-coord
     */
    public double latOrY() {
        return latOrY;
    }

    /**
     * Returns the longitude (geo) or x-coord (grid) data value.
     *
     * @return geo longitude or grid x-coord
     */
    public double longOrX() {
        return longOrX;
    }

    /**
     * Returns the location type (geo or grid), which indicates how the data
     * is to be interpreted.
     *
     * @return location type
     */
    public Type locType() {
        return locType;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("id", id)
                .add("lat/Y", latOrY)
                .add("long/X", longOrX)
                .add("loc-type", locType)
                .toString();
    }

    /**
     * Creates an instance of a layout location.
     *
     * @param id      an identifier for the item at this location
     * @param locType the location type
     * @param latOrY  geo latitude / grid y-coord
     * @param longOrX geo longitude / grid x-coord
     * @return layout location instance
     */
    public static LayoutLocation layoutLocation(String id, Type locType,
                                                double latOrY, double longOrX) {
        checkNotNull(id, "must supply an identifier");
        checkNotNull(locType, "must declare location type");
        return new LayoutLocation(id, locType, latOrY, longOrX);
    }

    /**
     * Creates an instance of a layout location.
     *
     * @param id      an identifier for the item at this location
     * @param locType the location type ("geo" or "grid")
     * @param latOrY  geo latitude / grid y-coord
     * @param longOrX geo longitude / grid x-coord
     * @return layout location instance
     * @throws IllegalArgumentException if the type is not "geo" or "grid"
     */
    public static LayoutLocation layoutLocation(String id, String locType,
                                                double latOrY, double longOrX) {
        Type t = Type.valueOf(locType.toUpperCase());
        return new LayoutLocation(id, t, latOrY, longOrX);
    }
}
