content: package com.actelion.research.chem.phesa.pharmacophore.pp;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import com.actelion.research.chem.Coordinates;
  import com.actelion.research.chem.StereoMolecule;
  
  public class ChargePoint implements IPharmacophorePoint {
  	private int chargeAtom;
  	private List<Integer> neighbours;
  	private int charge;
  	private Coordinates center;
  	private static final Coordinates directionality = new Coordinates(1.0,0.0,0.0);
  	
  	public ChargePoint(StereoMolecule mol, int a, List<Integer> neighbours, int charge) {
  		if(charge==0) 
  			throw new IllegalArgumentException("charge should not be 0 ");
  		chargeAtom = a;
  		this.neighbours = neighbours;
  		this.charge = charge;
  		updateCoordinates(mol.getAtomCoordinates());
  	}
  	
  	public ChargePoint(ChargePoint cP) {
  		chargeAtom = cP.chargeAtom;
  		charge = cP.charge;
  		center = new Coordinates(cP.center);
  		neighbours = new ArrayList<Integer>();
  		for(int neighbour : cP.neighbours) {
  			neighbours.add(neighbour);
  		}
  	}
  
  	@Override
  	public Coordinates getCenter() {
  		return center;
  	}
  
  	@Override
  	public void updateCoordinates(Coordinates[] coords) {
  		Coordinates com = new Coordinates(coords[chargeAtom]);
  		if(neighbours!=null) {
  			for(int neighbour:neighbours) {
  				com.add(coords[neighbour]);
  			}
  			com.scale(1.0/(neighbours.size()+1));
  		}
  
  		center = com;
  	}
  	
  	@Override
  	public Coordinates getDirectionality() {
  		// TODO Auto-generated method stub
  		return directionality;
  	}
  	
  	@Override
  	public Coordinates getRotatedDirectionality(double[][] rotMatrix,double scaleFactor) {
  		Coordinates directMod = new Coordinates(directionality);
  		return directMod;
  	}
  	
  	private ChargePoint(String ppString, StereoMolecule mol) {
  		decode(ppString,mol);
  	}
  	
  	public static ChargePoint fromString(String ppString, StereoMolecule mol) {
  		return new ChargePoint(ppString,mol);
  	}
  	
  
  	private void decode(String ppString, StereoMolecule mol) {
  		String[] strings = ppString.split(" ");
  		chargeAtom = Integer.decode(strings[1]);
  		charge = Integer.decode(strings[2]);
  		neighbours = new ArrayList<Integer>();
  		for(int i=3;i<strings.length;i++) {
  			neighbours.add(Integer.decode(strings[i]));
  		}
  		updateCoordinates(mol.getAtomCoordinates());
  	}
  
  	@Override
  	public String encode() {
  		StringBuilder molVolString = new StringBuilder();
  		molVolString.append("i");
  		molVolString.append(" ");
  		molVolString.append(Integer.toString(chargeAtom));
  		molVolString.append(" ");
  		molVolString.append(Integer.toString(charge));
  		molVolString.append(" ");
  		//molVolString.append(Integer.toString(neighbours.size()));
  		//molVolString.append(" ");
  		for(Integer neighbour : neighbours) {
  			molVolString.append(neighbour);
  			molVolString.append(" ");
  		}
  		return molVolString.toString().trim();
  	}
  
  	@Override
  	public double getSimilarity(IPharmacophorePoint pp) {
  		double result = 0.0;
  		if(pp instanceof ChargePoint) {
  			result = charge*((ChargePoint)pp).charge > 0 ? 1.0 : 0.0;
  		}
  		return result;
  	}
  
  	@Override
  	public int getCenterID() {
  		return chargeAtom;
  	}
  	
  	@Override
  	public void setCenterID(int centerID) {
  		chargeAtom = centerID;
  	}
  
  	@Override
  	public void setDirectionality(Coordinates directionality) {
  		return;
  
  	}
  	
  	public int getCharge() {
  		return charge;
  	}
  	
  	@Override
  	public void updateAtomIndices(int[] map) {
  		chargeAtom = map[chargeAtom];
  
  		for(int i=0;i<neighbours.size();i++) {
  			int neighbour = map[neighbours.get(i)];
  			neighbours.set(i, neighbour);
  		}
  	}
  
  	@Override
  	public int[] getAtomIndices() {
  		int [] a = {chargeAtom};
  		return a;
  	}
  
  
  	@Override
  	public IPharmacophorePoint copyPharmacophorePoint() {
  		// TODO Auto-generated method stub
  		return new ChargePoint(this);
  	}
  
  	@Override
  	public void getDirectionalityDerivativeCartesian(double[] grad, double[] v, Coordinates di, double sim) {
  		return; //no directionality 
  		
  	}
  	
  	@Override 
  	
  	public double getVectorSimilarity(IPharmacophorePoint pp2,Coordinates directionalityMod) {
  		return 1.0;
  	}
  		
  	@Override
  	 public double getVectorSimilarity(IPharmacophorePoint pp2) {
  		return 1.0;
  	}
  	
  	@Override
  	public int getFunctionalityIndex() {
  		if(charge<0)
  			return IPharmacophorePoint.Functionality.NEG_CHARGE.getIndex();
  		else
  			return IPharmacophorePoint.Functionality.POS_CHARGE.getIndex();
  	}
  
  	public int getChargeAtom() {
  		return chargeAtom;
  	}
  
  	public void setChargeAtom(int chargeAtom) {
  		this.chargeAtom = chargeAtom;
  	}
  
  	public List<Integer> getNeighbours() {
  		return neighbours;
  	}
  
  	public void setNeighbours(List<Integer> neighbours) {
  		this.neighbours = neighbours;
  	}
  
  }
  