From 1ff5d508273dbbbf8ca655ba3417f516eae2b510 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Fri, 7 Sep 2018 14:56:59 -0700
Subject: [PATCH] added lociAreEqual helper

---
 src/mol-model/loci.ts                           | 15 +++++++++++++++
 src/mol-model/shape/shape.ts                    | 11 +++++++++++
 src/mol-model/structure/structure/element.ts    | 11 +++++++++++
 src/mol-model/structure/structure/unit/links.ts | 15 +++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/src/mol-model/loci.ts b/src/mol-model/loci.ts
index d84498e13..8e0b1c715 100644
--- a/src/mol-model/loci.ts
+++ b/src/mol-model/loci.ts
@@ -22,4 +22,19 @@ export function isEmptyLoci(x: any): x is EmptyLoci {
     return !!x && x.kind === 'empty-loci';
 }
 
+export function areLociEqual(lociA: Loci, lociB: Loci) {
+    if (isEveryLoci(lociA) && isEveryLoci(lociB)) return true
+    if (isEmptyLoci(lociA) && isEmptyLoci(lociB)) return true
+    if (StructureElement.isLoci(lociA) && StructureElement.isLoci(lociB)) {
+        return StructureElement.areLociEqual(lociA, lociB)
+    }
+    if (Link.isLoci(lociA) && Link.isLoci(lociB)) {
+        return Link.areLociEqual(lociA, lociB)
+    }
+    if (Shape.isLoci(lociA) && Shape.isLoci(lociB)) {
+        return Shape.areLociEqual(lociA, lociB)
+    }
+    return false
+}
+
 export type Loci =  StructureElement.Loci | Link.Loci | EveryLoci | EmptyLoci | Shape.Loci
\ No newline at end of file
diff --git a/src/mol-model/shape/shape.ts b/src/mol-model/shape/shape.ts
index 58f930b6e..ffc602342 100644
--- a/src/mol-model/shape/shape.ts
+++ b/src/mol-model/shape/shape.ts
@@ -68,4 +68,15 @@ export namespace Shape {
     export function isLoci(x: any): x is Loci {
         return !!x && x.kind === 'group-loci';
     }
+
+    export function areLociEqual(a: Loci, b: Loci) {
+        if (a.groups.length !== b.groups.length) return false
+        for (let i = 0, il = a.groups.length; i < il; ++i) {
+            const groupA = a.groups[i]
+            const groupB = b.groups[i]
+            if (groupA.shape.id !== groupB.shape.id) return false
+            if (!OrderedSet.areEqual(groupA.ids, groupB.ids)) return false
+        }
+        return true
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model/structure/structure/element.ts b/src/mol-model/structure/structure/element.ts
index 0c83fbcd9..a8ad08e1a 100644
--- a/src/mol-model/structure/structure/element.ts
+++ b/src/mol-model/structure/structure/element.ts
@@ -63,6 +63,17 @@ namespace StructureElement {
         return !!x && x.kind === 'element-loci';
     }
 
+    export function areLociEqual(a: Loci, b: Loci) {
+        if (a.elements.length !== b.elements.length) return false
+        for (let i = 0, il = a.elements.length; i < il; ++i) {
+            const elementA = a.elements[i]
+            const elementB = b.elements[i]
+            if (elementA.unit.id !== elementB.unit.id) return false
+            if (!OrderedSet.areEqual(elementA.indices, elementB.indices)) return false
+        }
+        return true
+    }
+
     export function isLocation(x: any): x is StructureElement {
         return !!x && x.kind === 'element-location';
     }
diff --git a/src/mol-model/structure/structure/unit/links.ts b/src/mol-model/structure/structure/unit/links.ts
index 5534b62f0..12f24b5c0 100644
--- a/src/mol-model/structure/structure/unit/links.ts
+++ b/src/mol-model/structure/structure/unit/links.ts
@@ -32,6 +32,13 @@ namespace Link {
         return !!x && x.kind === 'link-location';
     }
 
+    export function areLocationsEqual(locA: Location, locB: Location) {
+        return (
+            locA.aIndex === locB.aIndex && locA.bIndex === locB.bIndex &&
+            locA.aUnit.id === locB.aUnit.id && locA.bUnit.id === locB.bUnit.id
+        )
+    }
+
     export interface Loci {
         readonly kind: 'link-loci',
         readonly links: ReadonlyArray<Location>
@@ -45,6 +52,14 @@ namespace Link {
         return !!x && x.kind === 'link-loci';
     }
 
+    export function areLociEqual(a: Loci, b: Loci) {
+        if (a.links.length !== b.links.length) return false
+        for (let i = 0, il = a.links.length; i < il; ++i) {
+            if (!areLocationsEqual(a.links[i], b.links[i])) return false
+        }
+        return true
+    }
+
     export function getType(structure: Structure, link: Location<Unit.Atomic>): LinkType {
         if (link.aUnit === link.bUnit) {
             const links = link.aUnit.links;
-- 
GitLab