package org.apache.samoa.moa.streams.clustering;

/*
 * #%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 java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Random;
import java.util.Vector;

import org.apache.samoa.instances.Attribute;
import org.apache.samoa.instances.DenseInstance;
import org.apache.samoa.instances.Instance;
import org.apache.samoa.instances.Instances;
import org.apache.samoa.instances.InstancesHeader;
import org.apache.samoa.moa.cluster.Clustering;
import org.apache.samoa.moa.cluster.SphereCluster;
import org.apache.samoa.moa.core.AutoExpandVector;
import org.apache.samoa.moa.core.DataPoint;
import org.apache.samoa.moa.core.FastVector;
import org.apache.samoa.moa.core.InstanceExample;
import org.apache.samoa.moa.core.ObjectRepository;
import org.apache.samoa.moa.streams.InstanceStream;
import org.apache.samoa.moa.tasks.TaskMonitor;

import com.github.javacliparser.FlagOption;
import com.github.javacliparser.FloatOption;
import com.github.javacliparser.IntOption;

public class RandomRBFGeneratorEvents extends ClusteringStream {
  private transient Vector listeners;

  private static final long serialVersionUID = 1L;

  public IntOption modelRandomSeedOption = new IntOption("modelRandomSeed",
      'm', "Seed for random generation of model.", 1);

  public IntOption instanceRandomSeedOption = new IntOption(
      "instanceRandomSeed", 'i',
      "Seed for random generation of instances.", 5);

  public IntOption numClusterOption = new IntOption("numCluster", 'K',
      "The average number of centroids in the model.", 5, 1, Integer.MAX_VALUE);

  public IntOption numClusterRangeOption = new IntOption("numClusterRange", 'k',
      "Deviation of the number of centroids in the model.", 3, 0, Integer.MAX_VALUE);

  public FloatOption kernelRadiiOption = new FloatOption("kernelRadius", 'R',
      "The average radii of the centroids in the model.", 0.07, 0, 1);

  public FloatOption kernelRadiiRangeOption = new FloatOption("kernelRadiusRange", 'r',
      "Deviation of average radii of the centroids in the model.", 0, 0, 1);

  public FloatOption densityRangeOption = new FloatOption("densityRange", 'd',
      "Offset of the average weight a cluster has. Value of 0 means all cluster " +
          "contain the same amount of points.", 0, 0, 1);

  public IntOption speedOption = new IntOption("speed", 'V',
      "Kernels move a predefined distance of 0.01 every X points", 500, 1, Integer.MAX_VALUE);

  public IntOption speedRangeOption = new IntOption("speedRange", 'v',
      "Speed/Velocity point offset", 0, 0, Integer.MAX_VALUE);

  public FloatOption noiseLevelOption = new FloatOption("noiseLevel", 'N',
      "Noise level", 0.1, 0, 1);

  public FlagOption noiseInClusterOption = new FlagOption("noiseInCluster", 'n',
      "Allow noise to be placed within a cluster");

  public IntOption eventFrequencyOption = new IntOption("eventFrequency", 'E',
      "Event frequency. Enable at least one of the events below and set numClusterRange!", 30000, 0, Integer.MAX_VALUE);

  public FlagOption eventMergeSplitOption = new FlagOption("eventMergeSplitOption", 'M',
      "Enable merging and splitting of clusters. Set eventFrequency and numClusterRange!");

  public FlagOption eventDeleteCreateOption = new FlagOption("eventDeleteCreate", 'C',
      "Enable emering and disapperaing of clusters. Set eventFrequency and numClusterRange!");

  private double merge_threshold = 0.7;
  private int kernelMovePointFrequency = 10;
  private double maxDistanceMoveThresholdByStep = 0.01;
  private int maxOverlapFitRuns = 50;
  private double eventFrequencyRange = 0;

  private boolean debug = false;

  private AutoExpandVector<GeneratorCluster> kernels;
  protected Random instanceRandom;
  protected InstancesHeader streamHeader;
  private int numGeneratedInstances;
  private int numActiveKernels;
  private int nextEventCounter;
  private int nextEventChoice = -1;
  private int clusterIdCounter;
  private GeneratorCluster mergeClusterA;
  private GeneratorCluster mergeClusterB;
  private boolean mergeKernelsOverlapping = false;

  private class GeneratorCluster implements Serializable {
    // TODO: points is redundant to microclusterpoints, we need to come
    // up with a good strategy that microclusters get updated and
    // rebuild if needed. Idea: Sort microclusterpoints by timestamp and let
    // microclusterdecay hold the timestamp for when the last point in a
    // microcluster gets kicked, then we rebuild... or maybe not... could be
    // same as searching for point to be kicked. more likely is we rebuild
    // fewer times then insert.

    private static final long serialVersionUID = -6301649898961112942L;

    SphereCluster generator;
    int kill = -1;
    boolean merging = false;
    double[] moveVector;
    int totalMovementSteps;
    int currentMovementSteps;
    boolean isSplitting = false;

    LinkedList<DataPoint> points = new LinkedList<DataPoint>();
    ArrayList<SphereCluster> microClusters = new ArrayList<SphereCluster>();
    ArrayList<ArrayList<DataPoint>> microClustersPoints = new ArrayList();
    ArrayList<Integer> microClustersDecay = new ArrayList();

    public GeneratorCluster(int label) {
      boolean outofbounds = true;
      int tryCounter = 0;
      while (outofbounds && tryCounter < maxOverlapFitRuns) {
        tryCounter++;
        outofbounds = false;
        double[] center = new double[numAttsOption.getValue()];
        double radius = kernelRadiiOption.getValue() + (instanceRandom.nextBoolean() ? -1 : 1)
            * kernelRadiiRangeOption.getValue() * instanceRandom.nextDouble();
        while (radius <= 0) {
          radius = kernelRadiiOption.getValue() + (instanceRandom.nextBoolean() ? -1 : 1)
              * kernelRadiiRangeOption.getValue() * instanceRandom.nextDouble();
        }
        for (int j = 0; j < numAttsOption.getValue(); j++) {
          center[j] = instanceRandom.nextDouble();
          if (center[j] - radius < 0 || center[j] + radius > 1) {
            outofbounds = true;
            break;
          }
        }
        generator = new SphereCluster(center, radius);
      }
      if (tryCounter < maxOverlapFitRuns) {
        generator.setId(label);
        double avgWeight = 1.0 / numClusterOption.getValue();
        double weight = avgWeight + (instanceRandom.nextBoolean() ? -1 : 1) * avgWeight * densityRangeOption.getValue()
            * instanceRandom.nextDouble();
        generator.setWeight(weight);
        setDesitnation(null);
      }
      else {
        generator = null;
        kill = 0;
        System.out.println("Tried " + maxOverlapFitRuns + " times to create kernel. Reduce average radii.");
      }
    }

    public GeneratorCluster(int label, SphereCluster cluster) {
      this.generator = cluster;
      cluster.setId(label);
      setDesitnation(null);
    }

    public int getWorkID() {
      for (int c = 0; c < kernels.size(); c++) {
        if (kernels.get(c).equals(this))
          return c;
      }
      return -1;
    }

    private void updateKernel() {
      if (kill == 0) {
        kernels.remove(this);
      }
      if (kill > 0) {
        kill--;
      }
      // we could be lot more precise if we would keep track of timestamps of
      // points
      // then we could remove all old points and rebuild the cluster on up to
      // date point base
      // BUT worse the effort??? so far we just want to avoid overlap with this,
      // so its more
      // konservative as needed. Only needs to change when we need a thighter
      // representation
      for (int m = 0; m < microClusters.size(); m++) {
        if (numGeneratedInstances - microClustersDecay.get(m) > decayHorizonOption.getValue()) {
          microClusters.remove(m);
          microClustersPoints.remove(m);
          microClustersDecay.remove(m);
        }
      }

      if (!points.isEmpty()
          && numGeneratedInstances - points.getFirst().getTimestamp() >= decayHorizonOption.getValue()) {
        // if(debug)
        // System.out.println("Cleaning up macro cluster "+generator.getId());
        points.removeFirst();
      }

    }

    private void addInstance(Instance instance) {
      DataPoint point = new DataPoint(instance, numGeneratedInstances);
      points.add(point);

      int minMicroIndex = -1;
      double minHullDist = Double.MAX_VALUE;
      boolean inserted = false;
      // we favour more recently build clusters so we can remove earlier cluster
      // sooner
      for (int m = microClusters.size() - 1; m >= 0; m--) {
        SphereCluster micro = microClusters.get(m);
        double hulldist = micro.getCenterDistance(point) - micro.getRadius();
        // point fits into existing cluster
        if (hulldist <= 0) {
          microClustersPoints.get(m).add(point);
          microClustersDecay.set(m, numGeneratedInstances);
          inserted = true;
          break;
        }
        // if not, check if its at least the closest cluster
        else {
          if (hulldist < minHullDist) {
            minMicroIndex = m;
            minHullDist = hulldist;
          }
        }
      }
      // Reseting index choice for alternative cluster building
      int alt = 1;
      if (alt == 1)
        minMicroIndex = -1;
      if (!inserted) {
        // add to closest cluster and expand cluster
        if (minMicroIndex != -1) {
          microClustersPoints.get(minMicroIndex).add(point);
          // we should keep the miniball instances and just check in
          // new points instead of rebuilding the whole thing
          SphereCluster s = new SphereCluster(microClustersPoints.get(minMicroIndex), numAttsOption.getValue());
          // check if current microcluster is bigger then generating cluster
          if (s.getRadius() > generator.getRadius()) {
            // remove previously added point
            microClustersPoints.get(minMicroIndex).remove(microClustersPoints.get(minMicroIndex).size() - 1);
            minMicroIndex = -1;
          }
          else {
            microClusters.set(minMicroIndex, s);
            microClustersDecay.set(minMicroIndex, numGeneratedInstances);
          }
        }
        // minMicroIndex might have been reset above
        // create new micro cluster
        if (minMicroIndex == -1) {
          ArrayList<DataPoint> microPoints = new ArrayList<DataPoint>();
          microPoints.add(point);
          SphereCluster s;
          if (alt == 0)
            s = new SphereCluster(microPoints, numAttsOption.getValue());
          else
            s = new SphereCluster(generator.getCenter(), generator.getRadius(), 1);

          microClusters.add(s);
          microClustersPoints.add(microPoints);
          microClustersDecay.add(numGeneratedInstances);
          int id = 0;
          while (id < kernels.size()) {
            if (kernels.get(id) == this)
              break;
            id++;
          }
          s.setGroundTruth(id);
        }
      }

    }

    private void move() {
      if (currentMovementSteps < totalMovementSteps) {
        currentMovementSteps++;
        if (moveVector == null) {
          return;
        }
        else {
          double[] center = generator.getCenter();
          boolean outofbounds = true;
          while (outofbounds) {
            double radius = generator.getRadius();
            outofbounds = false;
            center = generator.getCenter();
            for (int d = 0; d < center.length; d++) {
              center[d] += moveVector[d];
              if (center[d] - radius < 0 || center[d] + radius > 1) {
                outofbounds = true;
                setDesitnation(null);
                break;
              }
            }
          }
          generator.setCenter(center);
        }
      }
      else {
        if (!merging) {
          setDesitnation(null);
          isSplitting = false;
        }
      }
    }

    void setDesitnation(double[] destination) {

      if (destination == null) {
        destination = new double[numAttsOption.getValue()];
        for (int j = 0; j < numAttsOption.getValue(); j++) {
          destination[j] = instanceRandom.nextDouble();
        }
      }
      double[] center = generator.getCenter();
      int dim = center.length;

      double[] v = new double[dim];

      for (int d = 0; d < dim; d++) {
        v[d] = destination[d] - center[d];
      }
      setMoveVector(v);
    }

    void setMoveVector(double[] vector) {
      // we are ignoring the steps, otherwise we have to change
      // speed of the kernels, do we want that?
      moveVector = vector;
      int speedInPoints = speedOption.getValue();
      if (speedRangeOption.getValue() > 0)
        speedInPoints += (instanceRandom.nextBoolean() ? -1 : 1) * instanceRandom.nextInt(speedRangeOption.getValue());
      if (speedInPoints < 1)
        speedInPoints = speedOption.getValue();

      double length = 0;
      for (int d = 0; d < moveVector.length; d++) {
        length += Math.pow(vector[d], 2);
      }
      length = Math.sqrt(length);

      totalMovementSteps = (int) (length / (maxDistanceMoveThresholdByStep * kernelMovePointFrequency) * speedInPoints);
      for (int d = 0; d < moveVector.length; d++) {
        moveVector[d] /= (double) totalMovementSteps;
      }

      currentMovementSteps = 0;
      // if(debug){
      // System.out.println("Setting new direction for C"+generator.getId()+": distance "
      // +length+" in "+totalMovementSteps+" steps");
      // }
    }

    private String tryMerging(GeneratorCluster merge) {
      String message = "";
      double overlapDegree = generator.overlapRadiusDegree(merge.generator);
      if (overlapDegree > merge_threshold) {
        SphereCluster mcluster = merge.generator;
        double radius = Math.max(generator.getRadius(), mcluster.getRadius());
        generator.combine(mcluster);

        // //adjust radius, get bigger and bigger with high dim data
        generator.setRadius(radius);
        // double[] center = generator.getCenter();
        // double[] mcenter = mcluster.getCenter();
        // double weight = generator.getWeight();
        // double mweight = generator.getWeight();
        // // for (int i = 0; i < center.length; i++) {
        // // center[i] = (center[i] * weight + mcenter[i] * mweight) / (mweight
        // + weight);
        // // }
        // generator.setWeight(weight + mweight);
        message = "Clusters merging: " + mergeClusterB.generator.getId() + " into " + mergeClusterA.generator.getId();

        // clean up and restet merging stuff
        // mark kernel so it gets killed when it doesn't contain any more
        // instances
        merge.kill = decayHorizonOption.getValue();
        // set weight to 0 so no new instances will be created in the cluster
        mcluster.setWeight(0.0);
        normalizeWeights();
        numActiveKernels--;
        mergeClusterB = mergeClusterA = null;
        merging = false;
        mergeKernelsOverlapping = false;
      }
      else {
        if (overlapDegree > 0 && !mergeKernelsOverlapping) {
          mergeKernelsOverlapping = true;
          message = "Merge overlapping started";
        }
      }
      return message;
    }

    private String splitKernel() {
      isSplitting = true;
      // todo radius range
      double radius = kernelRadiiOption.getValue();
      double avgWeight = 1.0 / numClusterOption.getValue();
      double weight = avgWeight + avgWeight * densityRangeOption.getValue() * instanceRandom.nextDouble();
      SphereCluster spcluster = null;

      double[] center = generator.getCenter();
      spcluster = new SphereCluster(center, radius, weight);

      if (spcluster != null) {
        GeneratorCluster gc = new GeneratorCluster(clusterIdCounter++, spcluster);
        gc.isSplitting = true;
        kernels.add(gc);
        normalizeWeights();
        numActiveKernels++;
        return "Split from Kernel " + generator.getId();
      }
      else {
        System.out.println("Tried to split new kernel from C" + generator.getId() +
            ". Not enough room for new cluster, decrease average radii, number of clusters or enable overlap.");
        return "";
      }
    }

    private String fadeOut() {
      kill = decayHorizonOption.getValue();
      generator.setWeight(0.0);
      numActiveKernels--;
      normalizeWeights();
      return "Fading out C" + generator.getId();
    }

  }

  public RandomRBFGeneratorEvents() {
    noiseInClusterOption.set();
    // eventDeleteCreateOption.set();
    // eventMergeSplitOption.set();
  }

  public InstancesHeader getHeader() {
    return streamHeader;
  }

  public long estimatedRemainingInstances() {
    return -1;
  }

  public boolean hasMoreInstances() {
    return true;
  }

  public boolean isRestartable() {
    return true;
  }

  @Override
  public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) {
    monitor.setCurrentActivity("Preparing random RBF...", -1.0);
    generateHeader();
    restart();
  }

  public void restart() {
    instanceRandom = new Random(instanceRandomSeedOption.getValue());
    nextEventCounter = eventFrequencyOption.getValue();
    nextEventChoice = getNextEvent();
    numActiveKernels = 0;
    numGeneratedInstances = 0;
    clusterIdCounter = 0;
    mergeClusterA = mergeClusterB = null;
    kernels = new AutoExpandVector<GeneratorCluster>();

    initKernels();
  }

  protected void generateHeader() { // 2013/06/02: Noise label
    ArrayList<Attribute> attributes = new ArrayList<Attribute>();
    for (int i = 0; i < this.numAttsOption.getValue(); i++) {
      attributes.add(new Attribute("att" + (i + 1)));
    }

    ArrayList<String> classLabels = new ArrayList<String>();
    for (int i = 0; i < this.numClusterOption.getValue(); i++) {
      classLabels.add("class" + (i + 1));
    }
    if (noiseLevelOption.getValue() > 0)
      classLabels.add("noise"); // The last label = "noise"

    attributes.add(new Attribute("class", classLabels));
    streamHeader = new InstancesHeader(new Instances(getCLICreationString(InstanceStream.class), attributes, 0));
    streamHeader.setClassIndex(streamHeader.numAttributes() - 1);
  }

  protected void initKernels() {
    for (int i = 0; i < numClusterOption.getValue(); i++) {
      kernels.add(new GeneratorCluster(clusterIdCounter));
      numActiveKernels++;
      clusterIdCounter++;
    }
    normalizeWeights();
  }

  public InstanceExample nextInstance() {
    numGeneratedInstances++;
    eventScheduler();

    // make room for the classlabel
    double[] values_new = new double[numAttsOption.getValue()]; // +1
    double[] values = null;
    int clusterChoice = -1;

    if (instanceRandom.nextDouble() > noiseLevelOption.getValue()) {
      clusterChoice = chooseWeightedElement();
      values = kernels.get(clusterChoice).generator.sample(instanceRandom).toDoubleArray();
    }
    else {
      // get ranodm noise point
      values = getNoisePoint();
    }

    if (Double.isNaN(values[0])) {
      System.out.println("Instance corrupted:" + numGeneratedInstances);
    }
    System.arraycopy(values, 0, values_new, 0, values.length);

    Instance inst = new DenseInstance(1.0, values_new);
    inst.setDataset(getHeader());
    if (clusterChoice == -1) {
      // 2013/06/02 (Yunsu Kim)
      // Noise instance has the last class value instead of "-1"
      // Preventing ArrayIndexOutOfBoundsException in WriteStreamToARFFFile
      inst.setClassValue(numClusterOption.getValue());
    }
    else {
      inst.setClassValue(kernels.get(clusterChoice).generator.getId());
      // Do we need micro cluster representation if have overlapping clusters?
      // if(!overlappingOption.isSet())
      kernels.get(clusterChoice).addInstance(inst);
    }
    // System.out.println(numGeneratedInstances+": Overlap is"+updateOverlaps());

    return new InstanceExample(inst);
  }

  public Clustering getGeneratingClusters() {
    Clustering clustering = new Clustering();
    for (int c = 0; c < kernels.size(); c++) {
      clustering.add(kernels.get(c).generator);
    }
    return clustering;
  }

  public Clustering getMicroClustering() {
    Clustering clustering = new Clustering();
    int id = 0;

    for (int c = 0; c < kernels.size(); c++) {
      for (int m = 0; m < kernels.get(c).microClusters.size(); m++) {
        kernels.get(c).microClusters.get(m).setId(id);
        kernels.get(c).microClusters.get(m).setGroundTruth(kernels.get(c).generator.getId());
        clustering.add(kernels.get(c).microClusters.get(m));
        id++;
      }
    }

    // System.out.println("numMicroKernels "+clustering.size());
    return clustering;
  }

  /**************************** EVENTS ******************************************/
  private void eventScheduler() {

    for (int i = 0; i < kernels.size(); i++) {
      kernels.get(i).updateKernel();
    }

    nextEventCounter--;
    // only move kernels every 10 points, performance reasons????
    // should this be randomized as well???
    if (nextEventCounter % kernelMovePointFrequency == 0) {
      // move kernels
      for (int i = 0; i < kernels.size(); i++) {
        kernels.get(i).move();
        // overlapControl();
      }
    }

    if (eventFrequencyOption.getValue() == 0) {
      return;
    }

    String type = "";
    String message = "";
    boolean eventFinished = false;
    switch (nextEventChoice) {
    case 0:
      if (numActiveKernels > 1 && numActiveKernels > numClusterOption.getValue() - numClusterRangeOption.getValue()) {
        message = mergeKernels(nextEventCounter);
        type = "Merge";
      }
      if (mergeClusterA == null && mergeClusterB == null && message.startsWith("Clusters merging")) {
        eventFinished = true;
      }
      break;
    case 1:
      if (nextEventCounter <= 0) {
        if (numActiveKernels < numClusterOption.getValue() + numClusterRangeOption.getValue()) {
          type = "Split";
          message = splitKernel();
        }
        eventFinished = true;
      }
      break;
    case 2:
      if (nextEventCounter <= 0) {
        if (numActiveKernels > 1 && numActiveKernels > numClusterOption.getValue() - numClusterRangeOption.getValue()) {
          message = fadeOut();
          type = "Delete";
        }
        eventFinished = true;
      }
      break;
    case 3:
      if (nextEventCounter <= 0) {
        if (numActiveKernels < numClusterOption.getValue() + numClusterRangeOption.getValue()) {
          message = fadeIn();
          type = "Create";
        }
        eventFinished = true;
      }
      break;

    }
    if (eventFinished) {
      nextEventCounter = (int) (eventFrequencyOption.getValue() + (instanceRandom.nextBoolean() ? -1 : 1)
          * eventFrequencyOption.getValue() * eventFrequencyRange * instanceRandom.nextDouble());
      nextEventChoice = getNextEvent();
      // System.out.println("Next event choice: "+nextEventChoice);
    }
    if (!message.isEmpty()) {
      message += " (numKernels = " + numActiveKernels + " at " + numGeneratedInstances + ")";
      if (!type.equals("Merge") || message.startsWith("Clusters merging"))
        fireClusterChange(numGeneratedInstances, type, message);
    }
  }

  private int getNextEvent() {
    int choice = -1;
    boolean lowerLimit = numActiveKernels <= numClusterOption.getValue() - numClusterRangeOption.getValue();
    boolean upperLimit = numActiveKernels >= numClusterOption.getValue() + numClusterRangeOption.getValue();

    if (!lowerLimit || !upperLimit) {
      int mode = -1;
      if (eventDeleteCreateOption.isSet() && eventMergeSplitOption.isSet()) {
        mode = instanceRandom.nextInt(2);
      }

      if (mode == 0 || (mode == -1 && eventMergeSplitOption.isSet())) {
        // have we reached a limit? if not free choice
        if (!lowerLimit && !upperLimit)
          choice = instanceRandom.nextInt(2);
        else
        // we have a limit. if lower limit, choose split
        if (lowerLimit)
          choice = 1;
        // otherwise we reached upper level, choose merge
        else
          choice = 0;
      }

      if (mode == 1 || (mode == -1 && eventDeleteCreateOption.isSet())) {
        // have we reached a limit? if not free choice
        if (!lowerLimit && !upperLimit)
          choice = instanceRandom.nextInt(2) + 2;
        else
        // we have a limit. if lower limit, choose create
        if (lowerLimit)
          choice = 3;
        // otherwise we reached upper level, choose delete
        else
          choice = 2;
      }
    }

    return choice;
  }

  private String fadeOut() {
    int id = instanceRandom.nextInt(kernels.size());
    while (kernels.get(id).kill != -1)
      id = instanceRandom.nextInt(kernels.size());

    String message = kernels.get(id).fadeOut();
    return message;
  }

  private String fadeIn() {
    GeneratorCluster gc = new GeneratorCluster(clusterIdCounter++);
    kernels.add(gc);
    numActiveKernels++;
    normalizeWeights();
    return "Creating new cluster";
  }

  private String changeWeight(boolean increase) {
    double changeRate = 0.1;
    int id = instanceRandom.nextInt(kernels.size());
    while (kernels.get(id).kill != -1)
      id = instanceRandom.nextInt(kernels.size());

    int sign = 1;
    if (!increase)
      sign = -1;
    double weight_old = kernels.get(id).generator.getWeight();
    double delta = sign * numActiveKernels * instanceRandom.nextDouble() * changeRate;
    kernels.get(id).generator.setWeight(weight_old + delta);

    normalizeWeights();

    String message;
    if (increase)
      message = "Increase ";
    else
      message = "Decrease ";
    message += " weight on Cluster " + id + " from " + weight_old + " to " + (weight_old + delta);
    return message;

  }

  private String changeRadius(boolean increase) {
    double maxChangeRate = 0.1;
    int id = instanceRandom.nextInt(kernels.size());
    while (kernels.get(id).kill != -1)
      id = instanceRandom.nextInt(kernels.size());

    int sign = 1;
    if (!increase)
      sign = -1;

    double r_old = kernels.get(id).generator.getRadius();
    double r_new = r_old + sign * r_old * instanceRandom.nextDouble() * maxChangeRate;
    if (r_new >= 0.5)
      return "Radius to big";
    kernels.get(id).generator.setRadius(r_new);

    String message;
    if (increase)
      message = "Increase ";
    else
      message = "Decrease ";
    message += " radius on Cluster " + id + " from " + r_old + " to " + r_new;
    return message;
  }

  private String splitKernel() {
    int id = instanceRandom.nextInt(kernels.size());
    while (kernels.get(id).kill != -1)
      id = instanceRandom.nextInt(kernels.size());

    String message = kernels.get(id).splitKernel();

    return message;
  }

  private String mergeKernels(int steps) {
    if (numActiveKernels > 1 && ((mergeClusterA == null && mergeClusterB == null))) {

      // choose clusters to merge
      double diseredDist = steps / speedOption.getValue() * maxDistanceMoveThresholdByStep;
      double minDist = Double.MAX_VALUE;
      // System.out.println("DisredDist:"+(2*diseredDist));
      for (int i = 0; i < kernels.size(); i++) {
        for (int j = 0; j < i; j++) {
          if (kernels.get(i).kill != -1 || kernels.get(j).kill != -1) {
            continue;
          }
          else {
            double kernelDist = kernels.get(i).generator.getCenterDistance(kernels.get(j).generator);
            double d = kernelDist - 2 * diseredDist;
            // System.out.println("Dist:"+i+" / "+j+" "+d);
            if (Math.abs(d) < minDist &&
                (minDist != Double.MAX_VALUE || d > 0 || Math.abs(d) < 0.001)) {
              minDist = Math.abs(d);
              mergeClusterA = kernels.get(i);
              mergeClusterB = kernels.get(j);
            }
          }
        }
      }

      if (mergeClusterA != null && mergeClusterB != null) {
        double[] merge_point = mergeClusterA.generator.getCenter();
        double[] v = mergeClusterA.generator.getDistanceVector(mergeClusterB.generator);
        for (int i = 0; i < v.length; i++) {
          merge_point[i] = merge_point[i] + v[i] * 0.5;
        }

        mergeClusterA.merging = true;
        mergeClusterB.merging = true;
        mergeClusterA.setDesitnation(merge_point);
        mergeClusterB.setDesitnation(merge_point);

        if (debug) {
          System.out.println("Center1" + Arrays.toString(mergeClusterA.generator.getCenter()));
          System.out.println("Center2" + Arrays.toString(mergeClusterB.generator.getCenter()));
          System.out.println("Vector" + Arrays.toString(v));

          System.out.println("Try to merge cluster " + mergeClusterA.generator.getId() +
              " into " + mergeClusterB.generator.getId() +
              " at " + Arrays.toString(merge_point) +
              " time " + numGeneratedInstances);
        }
        return "Init merge";
      }
    }

    if (mergeClusterA != null && mergeClusterB != null) {

      // movekernels will move the kernels close to each other,
      // we just need to check and merge here if they are close enough
      return mergeClusterA.tryMerging(mergeClusterB);
    }

    return "";
  }

  /************************* TOOLS **************************************/

  public void getDescription(StringBuilder sb, int indent) {

  }

  private double[] getNoisePoint() {
    double[] sample = new double[numAttsOption.getValue()];
    boolean incluster = true;
    int counter = 20;
    while (incluster) {
      for (int j = 0; j < numAttsOption.getValue(); j++) {
        sample[j] = instanceRandom.nextDouble();
      }
      incluster = false;
      if (!noiseInClusterOption.isSet() && counter > 0) {
        counter--;
        for (int c = 0; c < kernels.size(); c++) {
          for (int m = 0; m < kernels.get(c).microClusters.size(); m++) {
            Instance inst = new DenseInstance(1, sample);
            if (kernels.get(c).microClusters.get(m).getInclusionProbability(inst) > 0) {
              incluster = true;
              break;
            }
          }
          if (incluster)
            break;
        }
      }
    }

    // double [] sample = new double [numAttsOption.getValue()];
    // for (int j = 0; j < numAttsOption.getValue(); j++) {
    // sample[j] = instanceRandom.nextDouble();
    // }

    return sample;
  }

  private int chooseWeightedElement() {
    double r = instanceRandom.nextDouble();

    // Determine index of choosen element
    int i = 0;
    while (r > 0.0) {
      r -= kernels.get(i).generator.getWeight();
      i++;
    }
    --i; // Overcounted once
    // System.out.println(i);
    return i;
  }

  private void normalizeWeights() {
    double sumWeights = 0.0;
    for (int i = 0; i < kernels.size(); i++) {
      sumWeights += kernels.get(i).generator.getWeight();
    }
    for (int i = 0; i < kernels.size(); i++) {
      kernels.get(i).generator.setWeight(kernels.get(i).generator.getWeight() / sumWeights);
    }
  }

  /*************** EVENT Listener *********************/
  // should go into the superclass of the generator, create new one for cluster
  // streams?

  /** Add a listener */
  synchronized public void addClusterChangeListener(ClusterEventListener l) {
    if (listeners == null)
      listeners = new Vector();
    listeners.addElement(l);
  }

  /** Remove a listener */
  synchronized public void removeClusterChangeListener(ClusterEventListener l) {
    if (listeners == null)
      listeners = new Vector();
    listeners.removeElement(l);
  }

  /** Fire a ClusterChangeEvent to all registered listeners */
  protected void fireClusterChange(long timestamp, String type, String message) {
    // if we have no listeners, do nothing...
    if (listeners != null && !listeners.isEmpty()) {
      // create the event object to send
      ClusterEvent event =
          new ClusterEvent(this, timestamp, type, message);

      // make a copy of the listener list in case
      // anyone adds/removes listeners
      Vector targets;
      synchronized (this) {
        targets = (Vector) listeners.clone();
      }

      // walk through the listener list and
      // call the sunMoved method in each
      Enumeration e = targets.elements();
      while (e.hasMoreElements()) {
        ClusterEventListener l = (ClusterEventListener) e.nextElement();
        l.changeCluster(event);

      }
    }
  }

  @Override
  public String getPurposeString() {
    return "Generates a random radial basis function stream.";
  }

  public String getParameterString() {
    return "";
  }

}
