// Translated by Nina
// This source code is under public domain
package net.morilib.nina.translate.sh;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.util.Map;
import net.morilib.sh.ShEnvironment;
import net.morilib.sh.ShFileSystem;
import net.morilib.sh.ShProcess;

public  class ReplaceSharp  implements ShProcess {

	static final int INITIAL = 0;

	private int STATE;
	private int unread = -1;
	private int gotoSymbol = -1;
	private String matched;

private Map<String, String> mp;
private StringBuffer b1;
private PrintStream ot;

ReplaceSharp() {}

private void _putmp() {
	String s, t;

	if((s = mp.get(t = b1.toString())) != null) {
		ot.print(s);
	} else {
		ot.print(t);
	}
	b1 = new StringBuffer();
}

public int main(ShEnvironment env,
		ShFileSystem fs,
		InputStream in,
		PrintStream out,
		PrintStream err,
		String... args) throws java.io.IOException {
	Reader d = new java.io.InputStreamReader(in);

	mp = new java.util.HashMap<String, String>();
	mp.put("class", env.find("CLASSNAME"));
	mp.put("package", env.find("PACKAGE"));
	b1 = new StringBuffer();
	ot = out;
	parse(d);
	return 0;
}


	private int _read(java.io.Reader rd) throws java.io.IOException {
		int c;

		if(gotoSymbol >= 0) {
			c = gotoSymbol;
			gotoSymbol = -1;
			return c;
		} else if(unread >= 0) {
			c = unread;
			unread = -1;
			return c;
		} else {
			return rd.read();
		}
	}

	void UNGET(int c) {
		unread = c;
	}

	void GOTOSYMBOL(int c) {
		gotoSymbol = c;
	}

	private boolean _step(int  $c) {
		switch(STATE) {
		case 0:
			if($c >= 34 && $c <= 34) {
				STATE = 1;
				return true;
			} else if($c >= 36 && $c <= 36) {
				STATE = 2;
				return true;
			} else {
				STATE = 0;
				return true;
			}
		case 2:
			if($c >= 36 && $c <= 36) {
				STATE = 3;
				return true;
			} else {
				STATE = 4;
				return true;
			}
		case 4:
			if($c >= 36 && $c <= 36) {
				STATE = 5;
				return true;
			} else {
				STATE = 4;
				return true;
			}
		case 5:
			return false;
		case 3:
			return false;
		case 1:
			if($c >= 34 && $c <= 34) {
				STATE = 0;
				return true;
			} else {
				STATE = 1;
				return true;
			}
		}
		return false;
	}

	private boolean _accepted() {
		return (STATE == 0 ||
				STATE == 1 ||
				STATE == 3 ||
				STATE == 4 ||
				STATE == 5);
	}

	private void _execaction(int  $c) {
		switch(STATE) {
		case 1:
			{ ot.print((char)$c); }
			break;
		case 5:
			{ _putmp();         
  STATE = INITIAL; }
			break;
		case 2:
			break;
		case 3:
			{ ot.print("$$");   
  STATE = INITIAL; }
			break;
		case 4:
			{ b1.appendCodePoint($c); }
			break;
		case 0:
			{ if($c >= 0)  ot.print((char)$c); }
			break;
		}
	}

	public boolean matches(String s) {
		int n;

		STATE = 0;  matched = null;
		for(n = 0; n < s.length(); n++) {
			if(!_step(s.charAt(n))) {
				return false;
			}
		}

		if(_accepted()) {
			matched = s;
			return true;
		} else {
			return false;
		}
	}

	public boolean lookingAt(String s) {
		StringBuffer b = new StringBuffer();
		int n;

		STATE = 0;  matched = null;
		for(n = 0; n < s.length(); n++) {
			if(_accepted()) {
				matched = b.toString();
			}

			if(_step(s.charAt(n))) {
				// do nothing
			} else {
				return matched != null;
			}
			b.append(s.charAt(n));
		}

		if(_accepted()) {
			matched = b.toString();
			return true;
		} else {
			return matched != null;
		}
	}

	public boolean find(String s) {
		StringBuffer b;
		int n, k;

		STATE = 0;  matched = null;
		for(k = 0; k < s.length(); k++) {
			b = new StringBuffer();
			for(n = k; n < s.length(); n++) {
				if(_accepted()) {
					matched = b.toString();
				}

				if(_step(s.charAt(n))) {
					// do noting
				} else if(matched == null) {
					break;
				} else {
					return true;
				}
				b.append(s.charAt(n));
			}

			if(_accepted()) {
				matched = b.toString();
				return true;
			} else if(matched != null) {
				return true;
			} else {
				STATE = 0;
			}
		}
		return false;
	}

	public String group() {
		return matched;
	}

	public boolean parse(
			java.io.Reader rd) throws java.io.IOException {
		int c;

		_execaction(-2);
		while((c = _read(rd)) >= 0) {
			if(!_step(c)) {
				throw new RuntimeException();
			}
			_execaction(c);
		}
		return _accepted();
	}

}
