package com.yahoo.labs.samoa.moa.cluster;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * 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.
 * #L%
 */

import com.yahoo.labs.samoa.instances.DenseInstance;
import com.yahoo.labs.samoa.instances.Instance;
import java.util.List;
import java.util.Random;

/**
 * A simple implementation of the <code>Cluster</code> interface representing spherical clusters. The inclusion
 * probability is one inside the sphere and zero everywhere else.
 * 
 */
public class SphereCluster extends Cluster {

  private static final long serialVersionUID = 1L;

  private double[] center;
  private double radius;
  private double weight;

  public SphereCluster(double[] center, double radius) {
    this(center, radius, 1.0);
  }

  public SphereCluster() {
  }

  public SphereCluster(double[] center, double radius, double weightedSize) {
    this();
    this.center = center;
    this.radius = radius;
    this.weight = weightedSize;
  }

  public SphereCluster(int dimensions, double radius, Random random) {
    this();
    this.center = new double[dimensions];
    this.radius = radius;

    // Position randomly but keep hypersphere inside the boundaries
    double interval = 1.0 - 2 * radius;
    for (int i = 0; i < center.length; i++) {
      this.center[i] = (random.nextDouble() * interval) + radius;
    }
    this.weight = 0.0;
  }

  public SphereCluster(List<? extends Instance> instances, int dimension) {
    this();
    if (instances == null || instances.size() <= 0)
      return;

    weight = instances.size();

    Miniball mb = new Miniball(dimension);
    mb.clear();

    for (Instance instance : instances) {
      mb.check_in(instance.toDoubleArray());
    }

    mb.build();
    center = mb.center();
    radius = mb.radius();
    mb.clear();
  }

  /**
   * Checks whether two <code>SphereCluster</code> overlap based on radius NOTE: overlapRadiusDegree only calculates the
   * overlap based on the centers and the radi, so not the real overlap
   * 
   * TODO: should we do this by MC to get the real overlap???
   * 
   * @param other
   * @return
   */

  public double overlapRadiusDegree(SphereCluster other) {

    double[] center0 = getCenter();
    double radius0 = getRadius();

    double[] center1 = other.getCenter();
    double radius1 = other.getRadius();

    double radiusBig;
    double radiusSmall;
    if (radius0 < radius1) {
      radiusBig = radius1;
      radiusSmall = radius0;
    }
    else {
      radiusBig = radius0;
      radiusSmall = radius1;
    }

    double dist = 0;
    for (int i = 0; i < center0.length; i++) {
      double delta = center0[i] - center1[i];
      dist += delta * delta;
    }
    dist = Math.sqrt(dist);

    if (dist > radiusSmall + radiusBig)
      return 0;
    if (dist + radiusSmall <= radiusBig) {
      // one lies within the other
      return 1;
    }
    else {
      return (radiusSmall + radiusBig - dist) / (2 * radiusSmall);
    }
  }

  public void combine(SphereCluster cluster) {
    double[] center = getCenter();
    double[] newcenter = new double[center.length];
    double[] other_center = cluster.getCenter();
    double other_weight = cluster.getWeight();
    double other_radius = cluster.getRadius();

    for (int i = 0; i < center.length; i++) {
      newcenter[i] = (center[i] * getWeight() + other_center[i] * other_weight) / (getWeight() + other_weight);
    }

    center = newcenter;
    double r_0 = getRadius() + Math.abs(distance(center, newcenter));
    double r_1 = other_radius + Math.abs(distance(other_center, newcenter));
    radius = Math.max(r_0, r_1);
    weight += other_weight;
  }

  public void merge(SphereCluster cluster) {
    double[] c0 = getCenter();
    double w0 = getWeight();
    double r0 = getRadius();

    double[] c1 = cluster.getCenter();
    double w1 = cluster.getWeight();
    double r1 = cluster.getRadius();

    // vector
    double[] v = new double[c0.length];
    // center distance
    double d = 0;

    for (int i = 0; i < c0.length; i++) {
      v[i] = c0[i] - c1[i];
      d += v[i] * v[i];
    }
    d = Math.sqrt(d);

    double r;
    double[] c = new double[c0.length];

    // one lays within the others
    if (d + r0 <= r1 || d + r1 <= r0) {
      if (d + r0 <= r1) {
        r = r1;
        c = c1;
      }
      else {
        r = r0;
        c = c0;
      }
    }
    else {
      r = (r0 + r1 + d) / 2.0;
      for (int i = 0; i < c.length; i++) {
        c[i] = c1[i] - v[i] / d * (r1 - r);
      }
    }

    setCenter(c);
    setRadius(r);
    setWeight(w0 + w1);

  }

  @Override
  public double[] getCenter() {
    double[] copy = new double[center.length];
    System.arraycopy(center, 0, copy, 0, center.length);
    return copy;
  }

  public void setCenter(double[] center) {
    this.center = center;
  }

  public double getRadius() {
    return radius;
  }

  public void setRadius(double radius) {
    this.radius = radius;
  }

  @Override
  public double getWeight() {
    return weight;
  }

  public void setWeight(double weight) {
    this.weight = weight;
  }

  @Override
  public double getInclusionProbability(Instance instance) {
    if (getCenterDistance(instance) <= getRadius()) {
      return 1.0;
    }
    return 0.0;
  }

  public double getCenterDistance(Instance instance) {
    double distance = 0.0;
    // get the center through getCenter so subclass have a chance
    double[] center = getCenter();
    for (int i = 0; i < center.length; i++) {
      double d = center[i] - instance.value(i);
      distance += d * d;
    }
    return Math.sqrt(distance);
  }

  public double getCenterDistance(SphereCluster other) {
    return distance(getCenter(), other.getCenter());
  }

  /*
   * the minimal distance between the surface of two clusters. is negative if
   * the two clusters overlap
   */
  public double getHullDistance(SphereCluster other) {
    double distance;
    // get the center through getCenter so subclass have a chance
    double[] center0 = getCenter();
    double[] center1 = other.getCenter();
    distance = distance(center0, center1);

    distance = distance - getRadius() - other.getRadius();
    return distance;
  }

  /*
   */
  /**
   * When a clusters looses points the new minimal bounding sphere can be partly outside of the originating cluster. If
   * a another cluster is right next to the original cluster (without overlapping), the new cluster can be overlapping
   * with this second cluster. OverlapSave will tell you if the current cluster can degenerate so much that it overlaps
   * with cluster 'other'
   * 
   * @param other
   *          the potentially overlapping cluster
   * @return true if cluster can potentially overlap
   */
  public boolean overlapSave(SphereCluster other) {
    // use basic geometry to figure out the maximal degenerated cluster
    // comes down to Max(radius *(sin alpha + cos alpha)) which is
    double minDist = Math.sqrt(2) * (getRadius() + other.getRadius());
    double diff = getCenterDistance(other) - minDist;

    return diff > 0;
  }

  private double distance(double[] v1, double[] v2) {
    double distance = 0.0;
    double[] center = getCenter();
    for (int i = 0; i < center.length; i++) {
      double d = v1[i] - v2[i];
      distance += d * d;
    }
    return Math.sqrt(distance);
  }

  public double[] getDistanceVector(Instance instance) {
    return distanceVector(getCenter(), instance.toDoubleArray());
  }

  public double[] getDistanceVector(SphereCluster other) {
    return distanceVector(getCenter(), other.getCenter());
  }

  private double[] distanceVector(double[] v1, double[] v2) {
    double[] v = new double[v1.length];
    for (int i = 0; i < v1.length; i++) {
      v[i] = v2[i] - v1[i];
    }
    return v;
  }

  /**
   * Samples this cluster by returning a point from inside it.
   * 
   * @param random
   *          a random number source
   * @return a point that lies inside this cluster
   */
  public Instance sample(Random random) {
    // Create sample in hypersphere coordinates
    // get the center through getCenter so subclass have a chance
    double[] center = getCenter();

    final int dimensions = center.length;

    final double sin[] = new double[dimensions - 1];
    final double cos[] = new double[dimensions - 1];
    final double length = random.nextDouble() * getRadius();

    double lastValue = 1.0;
    for (int i = 0; i < dimensions - 1; i++) {
      double angle = random.nextDouble() * 2 * Math.PI;
      sin[i] = lastValue * Math.sin(angle); // Store cumulative values
      cos[i] = Math.cos(angle);
      lastValue = sin[i];
    }

    // Calculate cartesian coordinates
    double res[] = new double[dimensions];

    // First value uses only cosines
    res[0] = center[0] + length * cos[0];

    // Loop through 'middle' coordinates which use cosines and sines
    for (int i = 1; i < dimensions - 1; i++) {
      res[i] = center[i] + length * sin[i - 1] * cos[i];
    }

    // Last value uses only sines
    res[dimensions - 1] = center[dimensions - 1] + length * sin[dimensions - 2];

    return new DenseInstance(1.0, res);
  }

  @Override
  protected void getClusterSpecificInfo(List<String> infoTitle, List<String> infoValue) {
    super.getClusterSpecificInfo(infoTitle, infoValue);
    infoTitle.add("Radius");
    infoValue.add(Double.toString(getRadius()));
  }

}
