/*
 * Created on 9. okt.. 2006
 *
 * Copyright (c) 2005, Karl Trygve Kalleberg <karltk near strategoxt.org>
 * 
 * Licensed under the GNU General Public License, v2
 */
package org.strategoxt.lang.terms;

import org.spoofax.interpreter.terms.IStrategoList;
import org.spoofax.interpreter.terms.IStrategoString;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.ITermPrinter;


public class StrategoString extends StrategoTerm implements IStrategoString {

	private final int storageType;
	
    private String value;
    
    public StrategoString(String value, IStrategoList annotations, int storageType) {
        super(annotations);
        this.value = value;
        this.storageType = storageType;
        initImmutableHashCode();
    }
    
    public int getStorageType() {
    	return storageType;
    }
    
    public IStrategoTerm getSubterm(int index) {
        throw new IndexOutOfBoundsException();
    }

    public IStrategoTerm[] getAllSubterms() {
        return TermFactory.EMPTY;
    }
    
    public int getSubtermCount() {
        return 0;
    }

    public int getTermType() {
        return IStrategoTerm.STRING;
    }

    @Override
    protected boolean doSlowMatch(IStrategoTerm second, int commonStorageType) {
        if(second.getTermType() != IStrategoTerm.STRING)
            return false;
        
        String value = stringValue();
        String secondValue = ((IStrategoString) second).stringValue();
        
        if (value == secondValue) {
        	// Do nothing
        } else if (value.equals(secondValue)) {
        	if (commonStorageType == SHARABLE)
        		this.value = secondValue;
        } else {
            return false;
        }

        IStrategoList annotations = getAnnotations();
        IStrategoList secondAnnotations = second.getAnnotations();
        if (annotations == secondAnnotations) {
        	return true;
        } else if (annotations.match(secondAnnotations)) {
        	if (commonStorageType == SHARABLE) internalSetAnnotations(secondAnnotations);
        	return true;
        } else {
        	return false;
        }
    }

    public String stringValue() {
        return value;
    }
    
    public void prettyPrint(ITermPrinter pp) {
        pp.print("\"" + stringValue().replace("\\", "\\\\").replace("\"", "\\\"") + "\"");
        printAnnotations(pp);
    }
 
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("\"");
        result.append(stringValue().replace("\\", "\\\\").replace("\"", "\\\""));
        result.append("\"");
        appendAnnotations(result);
        return result.toString();
    }
    
    @Override
    public int hashFunction() {
        return stringValue().hashCode();
    }
    
}

@@ -2275,19 +2275,36 @@
 int(%22%5C%22%22
- + 
+);%0A        pp.print(
 stringVa
@@ -2356,11 +2356,81 @@
 %5C%22%22)
- + 
+%0A        %09%09.replace(%22%5Cn%22, %22%5C%5Cn%22).replace(%22%5Cr%22, %22%5C%5Cr%22));%0A        pp.print(
 %22%5C%22%22
@@ -2675,16 +2675,69 @@
  %22%5C%5C%5C%22%22)
+%0A        %09%09.replace(%22%5Cn%22, %22%5C%5Cn%22).replace(%22%5Cr%22, %22%5C%5Cr%22)
 );%0A     

Escape newlines when printing term strings.