/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  The ASF licenses this file to You
 * 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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */
package org.apache.abdera2.common.geo;

import java.util.Iterator;

public abstract class Multiple extends Position implements Iterable<Coordinate> {

  private static final long serialVersionUID = -401256381030284678L;
    protected Coordinates coordinates;

    public Multiple() {
    }

    public Multiple(Multiple... multiples) {
        this.coordinates = new Coordinates();
        for (Multiple m : multiples)
            coordinates.add(m.getCoordinates());
    }

    public Multiple(Multiple multiple) {
        this(multiple.getCoordinates().clone());
    }

    public Multiple(Point point) {
        this(point.getCoordinate().clone());
    }

    public Multiple(Point... points) {
        this.coordinates = new Coordinates();
        for (Point p : points)
            coordinates.add(p.getCoordinate());
    }

    public Multiple(Coordinates coordinates) {
        this.coordinates = coordinates;
    }

    public Multiple(Coordinate... coordinates) {
        this.coordinates = new Coordinates(coordinates);
    }

    public Multiple(String value) {
        this.coordinates = new Coordinates(value);
    }

    public Multiple(double... values) {
        this.coordinates = new Coordinates();
        for (int n = 0; n < values.length; n = n + 2) {
            Coordinate c = new Coordinate(values[n], values[n + 1]);
            this.coordinates.add(c);
        }
    }

    public Coordinates getCoordinates() {
        return coordinates;
    }

    public void setCoordinates(Coordinates coordinates) {
        this.coordinates = coordinates;
    }

    public Iterator<Coordinate> iterator() {
        return coordinates.iterator();
    }

    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = super.hashCode();
        result = PRIME * result + ((coordinates == null) ? 0 : coordinates.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        final Multiple other = (Multiple)obj;
        if (coordinates == null) {
            if (other.coordinates != null)
                return false;
        } else if (!coordinates.equals(other.coordinates))
            return false;
        return true;
    }

    public int compareTo(Position o) {
        if (o == null || !this.getClass().isInstance(o) || equals(o))
            return 0;
        return coordinates.compareTo(((Multiple)o).coordinates);
    }

    protected void verify179Rule() {
        for (Coordinate c1 : getCoordinates()) {
            for (Coordinate c2 : getCoordinates()) {
                check179(c1.getLatitude(), c2.getLatitude());
                check179(c1.getLongitude(), c2.getLongitude());
            }
        }
    }

    private void check179(double d1, double d2) {
        if (Math.abs(Math.max(d1, d2)) - Math.abs(Math.min(d1, d2)) > 179)
            throw new RuntimeException("Values are greater than 179 degrees");
    }
}
