/*
* MX Cheminformatics Tools for Java
*
* Copyright (c) 2007, 2008 Metamolecular, LLC
*
* http://metamolecular.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.chemhack.jsMolEditor.client.io.mdl;
//import java.text.DecimalFormat;
//import java.text.DecimalFormatSymbols;
import java.util.List;
import java.util.ArrayList;
import com.chemhack.jsMolEditor.client.model.Atom;
import com.chemhack.jsMolEditor.client.model.Bond;
import com.chemhack.jsMolEditor.client.model.Molecule;
import com.google.gwt.i18n.client.NumberFormat;
/**
* @author Richard L. Apodaca
* Duan Lian
*/
public class MolfileWriter {
private static String ZERO2 = " 0";
private static String ZERO3 = " 0";
private static String CHIRAL_OFF = ZERO3;
private static String VERSION = " V2000";
private static String NEWLINE = "\n";
private static NumberFormat COORD = NumberFormat.getFormat("####0.0000");
private static String BLANK = " ";
private static String M = "M ";
private static String M_END = M + "END";
public MolfileWriter() {
}
public String write(Molecule molecule) {
Writer writer = new Writer();
writeHeader(molecule, writer);
writeCounts(molecule, writer);
writeAtoms(molecule, writer);
writeBonds(molecule, writer);
writeProperties(molecule, writer);
return writer.getString();
}
private void writeHeader(Molecule molecule, Writer writer) {
writeName(molecule, writer);
writeParameters(molecule, writer);
writeComments(molecule, writer);
}
private void writeName(Molecule molecule, Writer writer) {
writer.writeLine("[NO NAME]");
}
private void writeParameters(Molecule molecule, Writer writer) {
writer.writeLine(" jsMolEditor 2D");
}
private void writeComments(Molecule molecule, Writer writer) {
writer.writeLine("Created with jsMolEditor - http://chemhack.com/jsmoleditor");
}
private void writeCounts(Molecule molecule, Writer writer) {
writer.write(MDLStringKit.padLeft(String.valueOf(molecule.countAtoms()), 3));
writer.write(MDLStringKit.padLeft(String.valueOf(molecule.countBonds()), 3));
writer.write(ZERO3);
writer.write(ZERO3);
writer.write(CHIRAL_OFF);
for (int i = 0; i < 5; i++) {
writer.write(ZERO3);
}
writer.write(MDLStringKit.padLeft(String.valueOf(0), 3));
writer.write(VERSION);
writer.write(NEWLINE);
}
private void writeAtoms(Molecule molecule, Writer writer) {
for (int i = 0; i < molecule.countAtoms(); i++) {
Atom atom = molecule.getAtom(i);
writer.write(MDLStringKit.padLeft(COORD.format(atom.getX()), 10));
writer.write(MDLStringKit.padLeft(COORD.format(atom.getY()), 10));
writer.write(MDLStringKit.padLeft(COORD.format(atom.getZ()), 10));
writer.write(BLANK);
writer.write(MDLStringKit.padRight(atom.getSymbol().toString(), 3));
writer.write(ZERO2);
String chargeString = "0";
switch (atom.getCharge()) {
case 1:
chargeString = "3";
break;
case 2:
chargeString = "2";
break;
case 3:
chargeString = "1";
break;
case -1:
chargeString = "5";
break;
case -2:
chargeString = "6";
break;
case -3:
chargeString = "7";
break;
}
writer.write(MDLStringKit.padLeft(chargeString, 3));
for (int j = 0; j < 10; j++) {
writer.write(ZERO3);
}
writer.writeLine();
}
}
private void writeBonds(Molecule molecule, Writer writer) {
for (int i = 0; i < molecule.countBonds(); i++) {
Bond bond = molecule.getBond(i);
Atom source = bond.getSource();
Atom target = bond.getTarget();
int sourceIndex = source.getIndex() + 1;
int targetIndex = target.getIndex() + 1;
writer.write(MDLStringKit.padLeft(String.valueOf(sourceIndex), 3));
writer.write(MDLStringKit.padLeft(String.valueOf(targetIndex), 3));
writer.write(MDLStringKit.padLeft(String.valueOf(bond.getType()), 3));
writer.write(MDLStringKit.padLeft(String.valueOf(bond.getStereo()), 3));
for (int j = 0; j < 3; j++) {
writer.write(ZERO3);
}
writer.writeLine();
}
}
private void writeProperties(Molecule molecule, Writer writer) {
writeChargeProperty(molecule, writer);
writeIsotopicProperty(molecule, writer);
writeRadicalProperty(molecule, writer);
writer.write(M_END);
}
private void writeChargeProperty(Molecule molecule, Writer writer) {
List charges = new ArrayList();
List row = new ArrayList();
for (int i = 0; i < molecule.countAtoms(); i++) {
if (molecule.getAtom(i).getCharge() != 0) {
if (row.size() == 8) {
charges.add(row);
row = new ArrayList();
}
row.add(molecule.getAtom(i));
}
}
if (!charges.contains(row) && !row.isEmpty()) charges.add(row);
if (charges.isEmpty()) return;
for (int i = 0; i < charges.size(); i++) {
row = (List) charges.get(i);
writer.write(M + "CHG" + MDLStringKit.padLeft(String.valueOf(row.size()), 3));
for (int j = 0; j < row.size(); j++) {
Atom atom = (Atom) row.get(j);
int index = atom.getIndex() + 1;
//int index = molecule.getAtomIndex(atom) + 1;
int charge = atom.getCharge();
writer.write(" " + MDLStringKit.padLeft(String.valueOf(index), 3) + " " + MDLStringKit.padLeft(String.valueOf(charge), 3));
}
writer.writeLine();
}
}
private void writeIsotopicProperty(Molecule molecule, Writer writer) {
}
private void writeRadicalProperty(Molecule molecule, Writer writer) {
}
private class Writer {
private StringBuffer buffer;
private Writer() {
buffer = new StringBuffer();
}
public void write(String string) {
buffer.append(string);
}
public void writeLine(String string) {
buffer.append(string + "\n");
}
public void writeLine() {
buffer.append("\n");
}
public String getString() {
return buffer.toString();
}
}
}