/**
 * 
 */
package jp.mydns.masahase.abaqus;

import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import jp.mydns.masahase.AbaqusResult.AbaqusResultType;
import jp.mydns.masahase.AbaqusResult.ActiveFreedomType;
import jp.mydns.masahase.AbaqusResult.ElementCentroidRecordType;
import jp.mydns.masahase.AbaqusResult.ElementIntegPointRecordType;
import jp.mydns.masahase.AbaqusResult.ElementNodeRecord;
import jp.mydns.masahase.AbaqusResult.ElementRecordType;
import jp.mydns.masahase.AbaqusResult.ElementRefType;
import jp.mydns.masahase.AbaqusResult.ElementSetType;
import jp.mydns.masahase.AbaqusResult.ElementType;
import jp.mydns.masahase.AbaqusResult.IncrementType;
import jp.mydns.masahase.AbaqusResult.LoacalCoordinateType;
import jp.mydns.masahase.AbaqusResult.NodeOutputType;
import jp.mydns.masahase.AbaqusResult.NodeRefType;
import jp.mydns.masahase.AbaqusResult.NodeSetType;
import jp.mydns.masahase.AbaqusResult.NodeType;
import jp.mydns.masahase.AbaqusResult.ObjectFactory;
import jp.mydns.masahase.AbaqusResult.OutRequestType;
import jp.mydns.masahase.AbaqusResult.OutputValueType;

/**
 * 結果ファイルよりJAXBを用いてXMLに変換
 * 
 * @author MASA.H
 * @version 1.0
 */
public final class Fil2Xml_xjc {

	/**
	 * 単体動作用
	 * 
	 * @param args
	 *            実行時の引数
	 */
	public static void main(String[] args) {
		if (args.length != 2) {
			System.err.println("Need 2 argument.");
		} else {
			try {
				System.out.println("Initialize");
				Fil2Xml_xjc fj = new Fil2Xml_xjc();
				fj.setReadFile(args[0]);
				FileOutputStream fo = new FileOutputStream(args[1]);
				fj.setOutputStream(fo);
				System.out.println("Read result file.");
				fj.readFil();
				System.out.println("Write XML.");
				fj.writeXML();
				System.out.println("Node:" + fj.rootnode.getNode().size());
				System.out
						.println("Element:" + fj.rootnode.getElement().size());
				System.out.println("Finished");
			} catch (FileNotFoundException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			} catch (JAXBException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
	}

	public Fil2Xml_xjc() throws JAXBException {
		jaxb_objfctr = new ObjectFactory();
		jaxb_cntext = JAXBContext.newInstance("jp.mydns.masahase.AbaqusResult");
	}

	private ReadFil irf;
	JAXBContext jaxb_cntext;

	/**
	 * 読み取りファイル名の指定
	 * 
	 * @param filename
	 *            Abaqusの結果ファイルのファイル名
	 * @return 対応しているかどうか
	 */
	public boolean setReadFile(String filename) {
		Boolean ret = false;
		irf = new ReadFil();
		try {
			irf.setFileName(filename);
			ret = irf.isType();
		} catch (FileNotFoundException e) {
			ret = false;
		}
		return ret;
	}

	OutputStream xml_out;

	/**
	 * XMLの書き出し先を指定
	 * 
	 * @param os
	 *            書き出し先
	 */
	public void setOutputStream(OutputStream os) {
		xml_out = os;
	}

	ObjectFactory jaxb_objfctr;
	AbaqusResultType rootnode;

	/**
	 * XMLを書き出す
	 * 
	 * @throws JAXBException
	 */
	public void writeXML() throws JAXBException {
		if (xml_out != null) {
			Marshaller ms = jaxb_cntext.createMarshaller();
			ms.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
			ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			ms.marshal(rootnode, xml_out);
		}
	}

	/**
	 * 結果ファイルを読み取り、メモリ内に保持する
	 */
	public void readFil() {
		Object[] record;
		Object prev;
		try {
			labelRead();
			irf.rewind();
			int recordKey = irf.getNextRecordKey();
			rootnode = jaxb_objfctr.createAbaqusResultType();
			assert recordKey == 1921;
			record = irf.getRecordContents();
			prev = analizeRecord(null, recordKey, record);
			recordKey = irf.getNextRecordKey();
			while (recordKey > 0) {
				record = irf.getRecordContents();
				prev = analizeRecord(prev, recordKey, record);
				recordKey = irf.getNextRecordKey();
			}
		} catch(EOFException e ){
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	private Long LI2Long(Object obj) {
		Long ret;
		if (obj instanceof Long) {
			ret = (Long) obj;
		} else {
			assert obj instanceof Integer;
			ret = Long.valueOf(((Integer) obj).intValue());
		}
		return ret;
	}

	private Object analizeRecord(Object prev, int recordKey, Object[] content)
			throws DatatypeConfigurationException, ParseException {
		Object ret;
		switch (recordKey) {
		case 1921:
			ret = rkey1921(content);
			break;
		case 1900:
			ret = rkey1900(content);
			break;
		case 1990:
			ret = rkey1990(prev, content);
			break;
		case 1901:
			ret = rkey1901(content);
			break;
		case 1902:
			ret = rkey1902(content);
			break;
		case 1911:
			ret = rkey1911(content);
			break;
		case 1922:
			ret = rkey1922(content);
			break;
		case 1931:
			ret = rkey1931(content);
			break;
		case 1932:
			ret = rkey1932(prev, content);
			break;
		case 1933:
			ret = rkey1933(content);
			break;
		case 1934:
			ret = rkey1934(prev, content);
			break;
		case 2000:
			ret = rkey2000(content);
			break;
		case 2001:
			ret = rootnode;
			break;
		case 1:
			ret = rkey0001(prev, content);
			break;
		case 85:
			ret = rkey0085(prev, content);
			break;
		case 1940:
			ret = prev;
			break;
		default:
			if (eloutl.containsKey(recordKey)) {
				if (!(prev instanceof ElementRecordType)) {
					prev = rootnode.getIncrement().get(
							rootnode.getIncrement().size() - 1)
							.getElementRecord().get(
									rootnode.getIncrement().get(
											rootnode.getIncrement().size() - 1)
											.getElementRecord().size() - 1)
							.getValue();
				}
				analizeElementRecord((ElementRecordType) prev, recordKey,
						content);
				ret = prev;
			} else if (ndoutl.containsKey(recordKey)) {
				if (!(prev instanceof IncrementType)) {
					prev = rootnode.getIncrement().get(
							rootnode.getIncrement().size() - 1);
				}
				NodeOutputType no = jaxb_objfctr.createNodeOutputType();
				no.setNodeId(LI2Long(content[0]));
				no.setOutputVariable(ndoutl.get(recordKey));
				for (int i = 1; i < content.length; i++) {
					Serializable e;
					if (content[i] instanceof String) {
						e = (String) content[i];
					} else if (content[i] instanceof Double) {
						e = (Double) content[i];
					} else {
						e = Integer.valueOf(LI2Long(content[i]).intValue());
					}
					no.getFloatOrIntegerOrString().add(e);
				}
				rootnode.getIncrement().get(rootnode.getIncrement().size() - 1)
						.getNodeOutput().add(no);
				ret = prev;
			} else {
				System.err.println("Unsupport recordKey: "+recordKey);
				ret = prev;
			}
			break;
		}
		return ret;
	}

	private static HashMap<Integer, String> ndoutl, eloutl;

	/**
	 * @param prev
	 * @param content
	 * @return
	 */
	private Object rkey0085(Object prev, Object[] content) {
		Object ret;
		LoacalCoordinateType lc = jaxb_objfctr.createLoacalCoordinateType();
		lc.setC11((Double) content[0]);
		lc.setC12((Double) content[1]);
		lc.setC13((Double) content[2]);
		lc.setC21((Double) content[3]);
		lc.setC22((Double) content[4]);
		lc.setC23((Double) content[5]);
		if (!(prev instanceof ElementRecordType)) {
			prev = rootnode.getIncrement().get(
					rootnode.getIncrement().size() - 1).getElementRecord().get(
					rootnode.getIncrement().get(
							rootnode.getIncrement().size() - 1)
							.getElementRecord().size() - 1).getValue();
		}
		((ElementRecordType) prev).setLocalCoordinate(lc);
		ret = prev;
		return ret;
	}

	/**
	 * @param prev
	 * @param content
	 * @return
	 */
	private Object rkey0001(Object prev, Object[] content) {
		Object ret;
		ElementRecordType er;
		er = jaxb_objfctr.createElementRecordType();
		switch (LI2Long(content[3]).intValue()) {
		case 0:
			er = jaxb_objfctr.createElementIntegPointRecordType();
			((ElementIntegPointRecordType) er)
					.setElementId(LI2Long(content[0]));
			((ElementIntegPointRecordType) er).setIntegPointId(LI2Long(
					content[1]).shortValue());
			er.setLocate("integ_point");
			break;
		case 1:
			er = jaxb_objfctr.createElementCentroidRecordType();
			((ElementCentroidRecordType) er).setElementId(LI2Long(content[0]));
			er.setLocate("elem_senter");
			break;
		case 2:
			er = jaxb_objfctr.createElementNodeRecord();
			((ElementNodeRecord) er).setElemId(LI2Long(content[0]));
			((ElementNodeRecord) er).setNodeId(LI2Long(content[1]));
			er.setLocate("node");
			break;
		case 4:
			er = jaxb_objfctr.createElementNodeRecord();
			((ElementNodeRecord) er).setNodeId(LI2Long(content[0]));
			er.setLocate("noal_ave");
			break;
		case 3:
			er.setLocate("rebar");
			break;
		case 5:
			er = jaxb_objfctr.createElementCentroidRecordType();
			((ElementCentroidRecordType) er).setElementId(LI2Long(content[0]));
			er.setLocate("element");
			break;
		}
		er.setDirectStress(LI2Long(content[5]).shortValue());
		er.setShareStress(LI2Long(content[6]).shortValue());
		er.setDirection(LI2Long(content[7]).shortValue());
		er.setSections(LI2Long(content[8]).shortValue());
		if (prev instanceof IncrementType) {
			JAXBElement<ElementRecordType> e = jaxb_objfctr
					.createElementRecord(er);
			((IncrementType) prev).getElementRecord().add(e);
		} else {
			rootnode.getIncrement().get(rootnode.getIncrement().size() - 1)
					.getElementRecord().add(
							jaxb_objfctr.createElementRecord(er));
		}
		ret = er;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey2000(Object[] content) {
		Object ret;
		IncrementType inc = jaxb_objfctr.createIncrementType();
		inc.setTotalTime((Double) content[0]);
		inc.setStepTime((Double) content[1]);
		inc.setCsRateRatio((Double) content[2]);
		inc.setProcType(LI2Long(content[4]).shortValue());
		inc.setStepId(LI2Long(content[5]));
		inc.setIncId(LI2Long(content[6]));
		if (LI2Long(content[7]) == 1) {
			inc.setLinearPerturb(true);
		} else {
			inc.setLinearPerturb(false);
		}
		inc.setLpFactor((Double) content[8]);
		inc.setFreq((Double) content[9]);
		inc.setIncTime((Double) content[10]);
		String buf = new String();
		for (int i = 11; i < content.length; i++) {
			buf.concat((String) content[i]);
		}
		inc.setName(buf.replaceAll(" +$", ""));
		ret = inc;
		rootnode.getIncrement().add(inc);
		return ret;
	}

	/**
	 * @param prev
	 * @param content
	 * @return
	 */
	private Object rkey1934(Object prev, Object[] content) {
		Object ret;
		for (int i = 0; i < content.length; i++) {
			ElementRefType er = jaxb_objfctr.createElementRefType();
			er.setElementId(LI2Long(content[i]));
			((ElementSetType) prev).getElementRef().add(er);
		}
		ret = prev;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1933(Object[] content) {
		Object ret;
		ElementSetType es = jaxb_objfctr.createElementSetType();
		es.setName(SI2String(content[0]));
		for (int i = 1; i < content.length; i++) {
			ElementRefType er = jaxb_objfctr.createElementRefType();
			er.setElementId(LI2Long(content[i]));
			es.getElementRef().add(er);
		}
		rootnode.getElementSet().add(es);
		ret = es;
		return ret;
	}

	/**
	 * @param prev
	 * @param content
	 * @return
	 */
	private Object rkey1932(Object prev, Object[] content) {
		Object ret;
		for (int i = 0; i < content.length; i++) {
			NodeRefType nr = jaxb_objfctr.createNodeRefType();
			nr.setNodeId(LI2Long(content[i]));
			((NodeSetType) prev).getNodeRef().add(nr);
		}
		ret = prev;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1931(Object[] content) {
		Object ret;
		NodeSetType ns = jaxb_objfctr.createNodeSetType();
		ns.setName(SI2String(content[0]));
		for (int i = 1; i < content.length; i++) {
			NodeRefType nr = jaxb_objfctr.createNodeRefType();
			nr.setNodeId(LI2Long(content[i]));
			ns.getNodeRef().add(nr);
		}
		rootnode.getNodeSet().add(ns);
		ret = ns;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1922(Object[] content) {
		Object ret;
		rootnode.setTitle(((String) content[0] + (String) content[1]
				+ (String) content[2] + (String) content[3]
				+ (String) content[4] + (String) content[5]
				+ (String) content[6] + (String) content[7]
				+ (String) content[8] + (String) content[9]).replaceAll(" +$",
				""));
		ret = rootnode;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1911(Object[] content) {
		Object ret;
		OutRequestType ort = jaxb_objfctr.createOutRequestType();
		String tmp;
		switch (LI2Long(content[0]).intValue()) {
		case 0:
			tmp = "element";
			break;
		case 1:
			tmp = "node";
			break;
		case 2:
			tmp = "modal";
			break;
		case 3:
			tmp = "energy";
			break;
		default:
			tmp = "";
			break;
		}
		ort.setOutputType(tmp);
		ort.setName(SI2String(content[1]));
		if (content.length > 2) {
			ort.setElementType(SI2String(content[2]));
		}
		rootnode.getOutRequest().add(ort);
		ret = ort;
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1902(Object[] content) {
		Object ret;
		ActiveFreedomType af = jaxb_objfctr.createActiveFreedomType();
		af.setC1(LI2Long(content[0]).shortValue());
		af.setC2(LI2Long(content[1]).shortValue());
		af.setC3(LI2Long(content[2]).shortValue());
		af.setC4(LI2Long(content[3]).shortValue());
		af.setC5(LI2Long(content[4]).shortValue());
		af.setC6(LI2Long(content[5]).shortValue());
		ret = af;
		rootnode.setActiveFreedom(af);
		return ret;
	}

	/**
	 * @param content
	 * @return
	 */
	private Object rkey1901(Object[] content) {
		Object ret;
		NodeType nd = jaxb_objfctr.createNodeType();
		nd.setId(LI2Long(content[0]));
		nd.setC1(((Double) content[1]));
		if (content.length > 2) {
			nd.setC2(((Double) content[2]));
			if (content.length > 3) {
				nd.setC3(((Double) content[3]));
			}
		}
		ret = nd;
		rootnode.getNode().add(nd);
		return ret;
	}

	/**
	 * @param prev
	 * @param content
	 * @return
	 */
	private Object rkey1990(Object prev, Object[] content) {
		Object ret;
		for (int i = 0; i < content.length; i++) {
			NodeRefType nr = jaxb_objfctr.createNodeRefType();
			nr.setNodeId(LI2Long(content[i]));
			((ElementType) prev).getNodeRef().add(nr);
		}
		ret = prev;
		return ret;
	}

	/**
	 * @param content
	 */
	private AbaqusResultType rkey1921(Object[] content) {
		rootnode.setVersion(((String) content[0]).replaceAll(" +$", ""));
		try {
			{
				String sdate = ((String) content[1]) + ((String) content[2]);
				XMLGregorianCalendar gdate = DatatypeFactory.newInstance()
						.newXMLGregorianCalendar();
				Calendar tmp = Calendar.getInstance();
				tmp.setTime((new SimpleDateFormat("dd-MMM-yyyy", Locale.US))
						.parse(sdate.replaceAll(" +", "")));
				gdate.setDay(tmp.get(Calendar.DATE));
                if(tmp.get(Calendar.MONTH) != 0){
				    gdate.setMonth(tmp.get(Calendar.MONTH));
                }else{
                    gdate.setMonth(1);
                }
				gdate.setYear(tmp.get(Calendar.YEAR));
				gdate.setHour(DatatypeConstants.FIELD_UNDEFINED);
				gdate.setMinute(DatatypeConstants.FIELD_UNDEFINED);
				gdate.setSecond(DatatypeConstants.FIELD_UNDEFINED);
				rootnode.setDate(gdate);
			}
			{
				XMLGregorianCalendar gtime = DatatypeFactory.newInstance()
						.newXMLGregorianCalendar();
				String[] tmp = ((String) content[3]).split(":");
				gtime.setDay(DatatypeConstants.FIELD_UNDEFINED);
				gtime.setMonth(DatatypeConstants.FIELD_UNDEFINED);
				gtime.setYear(DatatypeConstants.FIELD_UNDEFINED);
				gtime.setHour(Integer.parseInt(tmp[0]));
				gtime.setMinute(Integer.parseInt(tmp[1]));
				gtime.setSecond(Integer.parseInt(tmp[2]));
				rootnode.setTime(gtime);
			}
		} catch (NumberFormatException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (DatatypeConfigurationException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		rootnode.setElements(LI2Long(content[4]));
		rootnode.setNodes(LI2Long(content[5]));
		rootnode.setTypicalLength((Double) content[6]);
		return rootnode;
	}

	private ElementType rkey1900(Object[] content) {
		ElementType elem = jaxb_objfctr.createElementType();
		elem.setId(LI2Long(content[0]));
		elem.setType(((String) content[1]).replaceAll(" +$", ""));
		for (int i = 2; i < content.length; i++) {
			NodeRefType nr = jaxb_objfctr.createNodeRefType();
			nr.setNodeId(LI2Long(content[i]));
			elem.getNodeRef().add(nr);
		}
		rootnode.getElement().add(elem);
		return elem;
	}

	private HashMap<Long, String> labels;

	private void labelRead() {
		try {
			labels = new HashMap<Long, String>();
			irf.rewind();
			int recordKey = irf.getNextRecordKey();
			while (recordKey != 1940) {
				recordKey = irf.getNextRecordKey();
				if (recordKey == 2000) {
					break;
				}
			}
			while (recordKey == 1940) {
				Object[] record = irf.getRecordContents();
				StringWriter sw = new StringWriter();
				String buf = new String();
				for (int i = 1; i < record.length; i++) {
					sw.write((String) record[i]);
				}
				buf = sw.toString();
				labels.put(LI2Long(record[0]), buf.replaceAll(" +$", ""));
				recordKey = irf.getNextRecordKey();
			}
		} catch (EOFException e) {
		}
	}

	private String SI2String(Object obj) {
		String ret;
		if ((obj instanceof Long) || (obj instanceof Integer)) {
			ret = labels.get(LI2Long(obj));
		} else {
			assert obj instanceof String;
			ret = ((String) obj).replaceAll(" +$", "");
			if (ret.matches(" *[0-9]+")) {
				ret = labels.get(Long.valueOf(ret.replaceAll(" +", "")));
			}
		}
		return ret;
	}

	private void analizeElementRecord(ElementRecordType prev, int recordKey,
			Object[] content) {
		OutputValueType ov = jaxb_objfctr.createOutputValueType();
		ov.setOutputVariable(eloutl.get(recordKey));
		for (int i = 0; i < content.length; i++) {
			Serializable e;
			if (content[i] instanceof String) {
				e = SI2String(content[i]);
			} else if (content[i] instanceof Double) {
				e = (Double) content[i];
			} else {
				e = Integer.valueOf(LI2Long(content[i]).intValue());
			}
			ov.getFloatOrIntegerOrString().add(e);
		}
		prev.getOutputValue().add(ov);
	}

	static {
		ndoutl = new HashMap<Integer, String>();
		eloutl = new HashMap<Integer, String>();
		eloutl.put(2, "TEMP");
		eloutl.put(3, "LOADS");
		eloutl.put(4, "FLUXS");
		eloutl.put(5, "SDV");
		eloutl.put(6, "VOIDR");
		eloutl.put(7, "FOUND");
		eloutl.put(8, "COORD");
		eloutl.put(9, "FV");
		eloutl.put(10, "NFLUX");
		eloutl.put(11, "S");
		eloutl.put(475, "CS11");
		eloutl.put(12, "SINV");
		eloutl.put(13, "SF");
		eloutl.put(449, "ESF1");
		eloutl.put(14, "ENER");
		eloutl.put(15, "NFORC");
		eloutl.put(17, "JK");
		eloutl.put(18, "POR");
		eloutl.put(19, "ELEN");
		eloutl.put(21, "E");
		eloutl.put(22, "PE");
		eloutl.put(23, "CE");
		eloutl.put(24, "IE");
		eloutl.put(25, "EE");
		eloutl.put(26, "CRACK");
		eloutl.put(27, "STH");
		eloutl.put(28, "HFL");
		eloutl.put(29, "SE");
		eloutl.put(30, "DG");
		eloutl.put(31, "CONF");
		eloutl.put(32, "SJP");
		eloutl.put(33, "FILM");
		eloutl.put(34, "RAD");
		eloutl.put(35, "SAT");
		eloutl.put(36, "SS");
		eloutl.put(38, "CONC");
		eloutl.put(446, "ISOL");
		eloutl.put(447, "ESOL");
		eloutl.put(448, "SOL");
		eloutl.put(39, "MFL");
		eloutl.put(40, "GELVR");
		eloutl.put(43, "FLUVR");
		eloutl.put(61, "STATUS");
		eloutl.put(73, "PEEQ");
		eloutl.put(74, "PRESS");
		eloutl.put(75, "MISES");
		eloutl.put(79, "RATIO");
		eloutl.put(80, "AMPCU");
		eloutl.put(83, "SSAVG");
		eloutl.put(86, "ALPHA");
		eloutl.put(87, "UVARM");
		eloutl.put(88, "THE");
		eloutl.put(89, "LE");
		eloutl.put(90, "NE");
		eloutl.put(91, "ER");
		eloutl.put(96, "MFLT");
		eloutl.put(97, "FLVEL");
		eloutl.put(476, "EMSF");
		eloutl.put(477, "EDT");
		eloutl.put(401, "SP");
		eloutl.put(402, "ALPHAP");
		eloutl.put(403, "EP");
		eloutl.put(404, "NEP");
		eloutl.put(405, "LEP");
		eloutl.put(406, "ERP");
		eloutl.put(407, "DGP");
		eloutl.put(408, "EEP");
		eloutl.put(409, "IEP");
		eloutl.put(410, "THEP");
		eloutl.put(411, "PEP");
		eloutl.put(412, "CEP");
		eloutl.put(413, "VVF");
		eloutl.put(414, "VVFG");
		eloutl.put(415, "VVFN");
		eloutl.put(416, "RD");
		eloutl.put(421, "CKE");
		eloutl.put(422, "CKLE");
		eloutl.put(423, "CKLS");
		eloutl.put(424, "CKSTAT");
		eloutl.put(441, "CKEMAG");
		eloutl.put(42, "SPE");
		eloutl.put(47, "SEPE");
		eloutl.put(462, "SEE");
		eloutl.put(463, "SEP");
		eloutl.put(464, "SALPHA");
		eloutl.put(495, "CTF");
		eloutl.put(496, "CEF");
		eloutl.put(497, "CVF");
		eloutl.put(498, "CSF");
		eloutl.put(499, "CSLST");
		eloutl.put(500, "CRF");
		eloutl.put(501, "CCF");
		eloutl.put(502, "CP");
		eloutl.put(503, "CU");
		eloutl.put(504, "CCU");
		eloutl.put(505, "CV");
		eloutl.put(506, "CA");
		eloutl.put(507, "CFAILST");
		eloutl.put(542, "CNF");
		eloutl.put(546, "CIVC");
		eloutl.put(548, "CASU");
		eloutl.put(556, "CUE");
		eloutl.put(557, "CUP");
		eloutl.put(558, "CUPEQ");
		eloutl.put(559, "CDMG");
		eloutl.put(560, "CDIF");
		eloutl.put(561, "CDIM");
		eloutl.put(562, "CDIP");
		eloutl.put(563, "CALPHAF");
		eloutl.put(44, "CFAILURE");
		eloutl.put(45, "PEQC");
		eloutl.put(473, "PEEQT");
		eloutl.put(22, "PE");
		eloutl.put(524, "VS");
		eloutl.put(525, "PS");
		eloutl.put(526, "VE");
		eloutl.put(50, "EPG");
		eloutl.put(442, "RBFOR");
		eloutl.put(443, "RBANG");
		eloutl.put(444, "RBROT");
		eloutl.put(445, "MFR");
		eloutl.put(46, "PHEPG");
		eloutl.put(49, "PHEFL");
		eloutl.put(51, "EFLX");
		eloutl.put(60, "CHRGS");
		eloutl.put(425, "ECD");
		eloutl.put(426, "ECURS");
		eloutl.put(427, "NCURS");
		eloutl.put(52, "XC");
		eloutl.put(53, "UC");
		eloutl.put(54, "VC");
		eloutl.put(55, "HC");
		eloutl.put(56, "HO");
		eloutl.put(57, "RI");
		eloutl.put(58, "MASS");
		eloutl.put(59, "VOL");
		eloutl.put(48, "TSHR");
		eloutl.put(62, "PHS");
		eloutl.put(63, "RS");
		eloutl.put(65, "PHE");
		eloutl.put(66, "RE");
		eloutl.put(508, "PHCTF");
		eloutl.put(509, "PHCEF");
		eloutl.put(510, "PHCVF");
		eloutl.put(520, "PHCSF");
		eloutl.put(512, "PHCU");
		eloutl.put(513, "PHCCU");
		eloutl.put(522, "PHCV");
		eloutl.put(523, "PHCA");
		eloutl.put(543, "PHCNF");
		eloutl.put(547, "PHCIVSL");
		eloutl.put(514, "RCTF");
		eloutl.put(516, "RCVF");
		eloutl.put(515, "RCEF");
		eloutl.put(517, "RCRF");
		eloutl.put(521, "RCSF");
		eloutl.put(518, "RCU");
		eloutl.put(519, "RCCU");
		eloutl.put(544, "RCNF");
		eloutl.put(94, "PHMFL");
		eloutl.put(95, "PHMFT");
		eloutl.put(76, "IVOL");
		eloutl.put(77, "SVOL");
		eloutl.put(78, "EVOL");
		eloutl.put(264, "VOLC");

		ndoutl.put(101, "U");
		ndoutl.put(102, "V");
		ndoutl.put(103, "A");
		ndoutl.put(104, "RF");
		ndoutl.put(105, "EPOT");
		ndoutl.put(106, "CF");
		ndoutl.put(107, "COORD");
		ndoutl.put(108, "POR");
		ndoutl.put(109, "RVF");
		ndoutl.put(110, "RVT");
		ndoutl.put(119, "RCHG");
		ndoutl.put(120, "CECHG");
		ndoutl.put(136, "PCAV");
		ndoutl.put(137, "CVOL");
		ndoutl.put(138, "RECUR");
		ndoutl.put(139, "CECUR");
		ndoutl.put(145, "VF");
		ndoutl.put(146, "TF");
		ndoutl.put(151, "PABS");
		ndoutl.put(201, "NT");
		ndoutl.put(204, "RFL");
		ndoutl.put(206, "CFL");
		ndoutl.put(214, "RFLE");
		ndoutl.put(221, "NNC");
		ndoutl.put(237, "MOT");
		ndoutl.put(320, "CFF");
		ndoutl.put(111, "PU");
		ndoutl.put(112, "PTU");
		ndoutl.put(113, "TU");
		ndoutl.put(114, "TV");
		ndoutl.put(115, "TA");
		ndoutl.put(116, "PPOR");
		ndoutl.put(117, "PHPOT");
		ndoutl.put(118, "PHCHG");
		ndoutl.put(123, "RU");
		ndoutl.put(124, "RTU");
		ndoutl.put(127, "RV");
		ndoutl.put(128, "RTV");
		ndoutl.put(131, "RA");
		ndoutl.put(132, "RTA");
		ndoutl.put(134, "RRF");
		ndoutl.put(135, "PRF");
		ndoutl.put(301, "GU");
		ndoutl.put(302, "GV");
		ndoutl.put(303, "GA");
		ndoutl.put(304, "BM");
		ndoutl.put(305, "GPU");
		ndoutl.put(306, "GPV");
		ndoutl.put(307, "GPA");
		ndoutl.put(308, "SNE");
		ndoutl.put(309, "KE");
		ndoutl.put(310, "T");
	}
}
