Clazz.declarePackage ("JS");
Clazz.load (["java.util.Hashtable"], "JS.CIPChirality", ["java.util.Arrays", "JU.BS", "$.Measure", "$.V3", "JU.BSUtil", "$.Logger"], function () {
c$ = Clazz.decorateAsClass (function () {
this.vwr = null;
this.htPathPoints = null;
if (!Clazz.isClassDefined ("JS.CIPChirality.CIPAtom")) {
JS.CIPChirality.$CIPChirality$CIPAtom$ ();
}
Clazz.instantialize (this, arguments);
}, JS, "CIPChirality");
Clazz.prepareFields (c$, function () {
this.htPathPoints =  new java.util.Hashtable ();
});
Clazz.makeConstructor (c$, 
function () {
});
Clazz.defineMethod (c$, "setViewer", 
function (vwr) {
this.vwr = vwr;
return this;
}, "JV.Viewer");
Clazz.defineMethod (c$, "getChirality", 
function (atom) {
var rs = 0;
var a;
if (atom.getCovalentBondCount () != 4 || !(a = Clazz.innerTypeInstance (JS.CIPChirality.CIPAtom, this, null, atom, null, false)).set ()) return rs;
try {
if (a.sortSubstituents ()) rs = JS.CIPChirality.getHandedness (a);
} catch (e) {
System.out.println (e + " in CIPChirality");
if (!this.vwr.isJS) e.printStackTrace ();
}
if (JU.Logger.debugging) JU.Logger.info (atom + " " + (rs == 1 ? "R" : rs == 2 ? "S" : ""));
return rs;
}, "JU.Node");
c$.getHandedness = Clazz.defineMethod (c$, "getHandedness", 
function (a) {
var p1 = a.atoms[0].atom;
var p2 = a.atoms[1].atom;
var p3 = a.atoms[2].atom;
var p4 = a.atoms[3].atom;
var vNorm =  new JU.V3 ();
var d = JU.Measure.getNormalThroughPoints (p1, p2, p3, vNorm,  new JU.V3 ());
return (JU.Measure.distanceToPlaneV (vNorm, d, p4) > 0 ? 1 : 2);
}, "JS.CIPChirality.CIPAtom");
c$.breakTie = Clazz.defineMethod (c$, "breakTie", 
function (a, b) {
var score = a.checkDuplicate (b);
if (score != 0) return score;
score = a.checkRule1b (b);
if (score != 0) return score;
if (a.atom === b.atom || !a.set () || !b.set () || a.isTerminal || b.isTerminal || a.isDuplicate && b.isDuplicate) return 0;
if (JU.Logger.debugging) JU.Logger.info ("tie for " + a + " and " + b);
if ((score = JS.CIPChirality.compareAB (a, b, true)) != 0) return score;
a.sortSubstituents ();
b.sortSubstituents ();
return JS.CIPChirality.compareAB (a, b, false);
}, "JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom");
c$.compareAB = Clazz.defineMethod (c$, "compareAB", 
 function (a, b, ignoreDuplicate) {
for (var i = 0; i < a.nAtoms; i++) {
var ai = a.atoms[i];
var bi = b.atoms[i];
System.out.println ("compareAB " + ai + " " + bi + " ignoreDup=" + ignoreDuplicate);
var score = (ignoreDuplicate ? ai.checkRules12 (bi) : JS.CIPChirality.breakTie (ai, bi));
if (score != 0) {
System.out.println ((score == 1 ? bi + " beatsi " + ai : ai + " beatsi " + bi) + " " + ignoreDuplicate);
return score;
}}
return 0;
}, "JS.CIPChirality.CIPAtom,JS.CIPChirality.CIPAtom,~B");
c$.$CIPChirality$CIPAtom$ = function () {
Clazz.pu$h(self.c$);
c$ = Clazz.decorateAsClass (function () {
Clazz.prepareCallback (this, arguments);
this.atom = null;
this.massNo = 0;
this.elemNo = 0;
this.parent = null;
this.isDuplicate = true;
this.isTerminal = false;
this.isSet = false;
this.isBelow = 0;
this.bsPath = null;
this.rootDistance = 0;
this.atoms = null;
this.nAtoms = 0;
Clazz.instantialize (this, arguments);
}, JS.CIPChirality, "CIPAtom", null, Comparable);
Clazz.defineMethod (c$, "toString", 
function () {
return (this.atom == null ? "<null>" : this.atom.toString ()) + (this.isDuplicate ? " *" : "" + " " + (this.isBelow + 1));
});
Clazz.makeConstructor (c$, 
function (a, b, c) {
if (a == null) return;
this.atom = a;
this.parent = b;
this.isTerminal = a.getCovalentBondCount () == 1;
this.elemNo = a.getElementNumber ();
this.massNo = a.getNominalMass ();
this.bsPath = (b == null ?  new JU.BS () : JU.BSUtil.copy (b.bsPath));
var d = a.getIndex ();
if (this.bsPath.get (d)) {
c = true;
this.rootDistance = this.b$["JS.CIPChirality"].htPathPoints.get ( new Integer (d)).intValue ();
} else {
this.bsPath.set (d);
this.rootDistance = (b == null ? 1 : b.rootDistance + 1);
this.b$["JS.CIPChirality"].htPathPoints.put ( new Integer (d),  new Integer (this.rootDistance));
}this.isDuplicate = c;
}, "JU.Node,JS.CIPChirality.CIPAtom,~B");
Clazz.defineMethod (c$, "set", 
function () {
if (this.isTerminal || this.isSet) return true;
this.isSet = true;
this.atoms =  new Array (this.parent == null ? 4 : 3);
if (this.atom == null) System.out.println ("HOHO");
var a = this.atom.getBondCount ();
var b = this.atom.getEdges ();
var c = 0;
for (var d = 0; d < a; d++) {
var e = b[d];
if (!e.isCovalent ()) continue;
var f = e.getOtherAtomNode (this.atom);
var g = (this.parent != null && this.parent.atom === f);
var h = e.getCovalentOrder ();
switch (h) {
case 3:
if (!this.addAtom (c++, f, g)) {
this.isTerminal = true;
return false;
}case 2:
if (!this.addAtom (c++, f, h != 2 || g)) {
this.isTerminal = true;
return false;
}case 1:
if (!g && !this.addAtom (c++, f, h != 1)) {
this.isTerminal = true;
return false;
}break;
default:
this.isTerminal = true;
return false;
}
}
this.isTerminal = (c == 0);
this.nAtoms = c;
for (; c < this.atoms.length; c++) this.atoms[c] = Clazz.innerTypeInstance (JS.CIPChirality.CIPAtom, this, null, null, null, true);

java.util.Arrays.sort (this.atoms);
return !this.isTerminal;
});
Clazz.defineMethod (c$, "addAtom", 
 function (a, b, c) {
if (a >= this.atoms.length) return false;
this.atoms[a] = Clazz.innerTypeInstance (JS.CIPChirality.CIPAtom, this, null, b, this, c);
System.out.println (this + " adding " + a + " " + this.atoms[a]);
return true;
}, "~N,JU.Node,~B");
Clazz.defineMethod (c$, "sortSubstituents", 
function () {
var a = (this.parent != null);
var b = this.atoms.length;
for (var c = 0; c < b; c++) this.atoms[c].isBelow = 0;

for (var d = 0; d < b; d++) {
var e = this.atoms[d];
for (var f = d + 1; f < b; f++) {
var g = this.atoms[f];
var h = e.compareTo (g);
if (JU.Logger.debugging) JU.Logger.info ("comparing parent=" + this.parent + " this=" + this + ": " + b + " " + d + " " + f + " " + e + " and " + g + " = " + h);
switch (h) {
case 1:
e.isBelow++;
System.out.println (g + " beatsc " + e);
break;
case -1:
g.isBelow++;
System.out.println (e + " beatsc " + g);
break;
case 0:
switch (JS.CIPChirality.breakTie (e, g)) {
case 0:
if (!a) return false;
case 1:
e.isBelow++;
System.out.println (g + " beatst " + e);
break;
case -1:
g.isBelow++;
System.out.println (e + " beatst " + g);
break;
}
break;
}
}
}
var e =  new Array (b);
for (var f = 0; f < b; f++) e[this.atoms[f].isBelow] = this.atoms[f];

if (JU.Logger.debugging) for (var g = 0; g < b; g++) JU.Logger.info (this.atom + "[" + g + "]=" + e[g]);

this.atoms = e;
return true;
});
Clazz.overrideMethod (c$, "compareTo", 
function (a) {
var b = 0;
return (b = this.checkRules12 (a)) != 0 ? b : this.checkDuplicate (a);
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod (c$, "checkRules12", 
function (a) {
var b = 0;
return (b = this.checkRule1a (a)) != 0 ? b : (b = this.checkRule1b (a)) != 0 ? b : this.checkRule2 (a);
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod (c$, "checkRule1a", 
function (a) {
return a.atom === this.atom ? 0 : a.atom == null ? -1 : this.atom == null ? 1 : a.elemNo != this.elemNo ? (a.elemNo < this.elemNo ? -1 : 1) : 0;
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod (c$, "checkRule1b", 
function (a) {
return !a.isDuplicate || !this.isDuplicate ? 0 : a.rootDistance < this.rootDistance ? 1 : a.rootDistance > this.rootDistance ? -1 : 0;
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod (c$, "checkRule2", 
function (a) {
return a.massNo < this.massNo ? -1 : a.massNo > this.massNo ? 1 : 0;
}, "JS.CIPChirality.CIPAtom");
Clazz.defineMethod (c$, "checkDuplicate", 
function (a) {
return a.isDuplicate == this.isDuplicate ? 0 : a.isDuplicate ? -1 : 1;
}, "JS.CIPChirality.CIPAtom");
c$ = Clazz.p0p ();
};
Clazz.defineStatics (c$,
"NO_CHIRALITY", 0,
"TIED", 0,
"B_WINS", 1,
"A_WINS", -1);
});
