package org.apache.samoa.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.tasks.TaskMonitor;
import org.apache.samoa.streams.InstanceStream;

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 "";
  }

}
