package de.dhbwstuttgart.typedeployment;

import java.util.Comparator;
import java.util.List;
import java.util.Set;

import org.antlr.v4.runtime.Token;

public class TypeInsertPoint {
    public Token point;
    private String insertString;
    private int extraOffset = 0;
    private KindOfTypeInsertPoint kind;

    public TypeInsertPoint(Token point, String toInsert, KindOfTypeInsertPoint kind){
        this.point = point;
        this.kind = kind;
        this.insertString = (toInsert.endsWith(" ")) ? toInsert : toInsert + " " ;
    }
    
    public boolean isGenericClassInsertPoint() {
    	return kind == KindOfTypeInsertPoint.GENERIC_CLASS_INSERT;
    }

    public String insert(String intoSource, List<TypeInsertPoint> additionalOffset){
        return new StringBuilder(intoSource).insert(point.getStartIndex()+extraOffset, insertString).toString();
    }

    public String getInsertString() {
        return insertString;
    }
       
    public void addExtraOffset(int toAdd) {
    	this.extraOffset += toAdd;
    }
    
    public int getPositionInCode() {
    	return point.getStartIndex() + extraOffset; 
    }
    
    /* PL 2018-06-19
     * Zwei TypeInsertPoint's sind gleich, wenn ihre point's gleich sind 
     * eingefuegt damit man TypeReplaceMarker vergleichen kann
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
    	return this == obj;
    	/*
    	if(!(obj instanceof TypeInsertPoint)) {
			return false;
    	}
    	else {
    		return 
	    		((TypeInsertPoint)obj).getPositionInCode() == this.getPositionInCode() &&
	    		((TypeInsertPoint)obj).insertString.equals(this.insertString);
    	}		
    	*/	
    }
    
    public int hashCode() {
    	return getPositionInCode() * 11 * insertString.hashCode();
    }
    
    public Set<TypeInsertPoint> getAdditionalPoints() {
    	return this.getAdditionalPoints();
    }
    
    public String toString() {
    	return point.getLine() + ":" + point.getCharPositionInLine() + ":" + insertString;
    }
    
    public static final class TypeInsertPointPositionComparator implements Comparator<TypeInsertPoint> {

    	@Override
    	public int compare(TypeInsertPoint o1, TypeInsertPoint o2) { 
    		if (o1.point == null && o2.point == null) {
    			return 0;
    		} else if (o2.point == null) {
    			return 1;
    		} else if (o1.point == null) {
    			return -1;
    		}
    		
    		if (o1.getPositionInCode() > o2.getPositionInCode()) {
    			return 1;
    		} else if (o1.getPositionInCode() < o2.getPositionInCode()) {
    			return -1;
    		}
    		return 0;
    	}

    }
}
