2a99d78cddf4b7de673435f911262ee25b36c238
braney
  Sun Feb 12 14:14:18 2023 -0800
ongoing work on snake display for chains and psls

diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 0374eb1..2902197 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -3664,39 +3664,84 @@
 struct dnaSeq *otherChromSeq(struct twoBitFile *otherTbf, char *otherDb, 
     char *otherChrom, int otherStart, int otherEnd)
 /* This fetches sequence from tdb->otherTwoBitUrl if available,  if not
  * tries to find it via otherDb */
 {
 if (otherTbf != NULL)
     {
     return twoBitReadSeqFrag(otherTbf, otherChrom, otherStart, otherEnd);
     }
 else
     {
     return hChromSeq(otherDb, otherChrom, otherStart, otherEnd);
     }
 }
 
+void doSnakeChainClick(struct trackDb *tdb, char *itemName)
+/* Put up page for chain snakes. */
+{
+struct trackDb *parentTdb = trackDbTopLevelSelfOrParent(tdb);
+char *otherSpecies = trackDbSetting(tdb, "otherSpecies");
+if (otherSpecies == NULL)
+    otherSpecies = trackHubSkipHubName(tdb->table) + strlen("snake");
+
+char *hubName = cloneString(database);
+char otherDb[4096];
+char *qName = cartOptionalString(cart, "qName");
+int qs = atoi(cartOptionalString(cart, "qs"));
+int qe = atoi(cartOptionalString(cart, "qe"));
+int qWidth = atoi(cartOptionalString(cart, "qWidth"));
+char *qTrack = cartString(cart, "g");
+if(isHubTrack(qTrack) && ! trackHubDatabase(database))
+    hubName = cloneString(qTrack);
+
+/* current mouse strain hal file has incorrect chrom names */
+char *aliasQName = qName;
+// aliasQName = "chr1";  // temporarily make this work for the mouse hal
+
+if(trackHubDatabase(database) || isHubTrack(qTrack))
+    {
+    char *ptr = strchr(hubName + 4, '_');
+    *ptr = 0;
+    safef(otherDb, sizeof otherDb, "%s_%s", hubName, otherSpecies);
+    }
+else
+    {
+    safef(otherDb, sizeof otherDb, "%s", otherSpecies);
+    }
+
+char headerText[256];
+safef(headerText, sizeof headerText, "reference: %s, query: %s\n", trackHubSkipHubName(database), trackHubSkipHubName(otherDb) );
+genericHeader(parentTdb, headerText);
+
+printf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d&%s_snake%s=full\" TARGET=_BLANK>%s:%d-%d</A> link to block in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, qs, qe, hubName, trackHubSkipHubName(database), aliasQName, qs, qe, trackHubSkipHubName(otherDb));
+
+int qCenter = (qs + qe) / 2;
+int newQs = qCenter - qWidth/2;
+int newQe = qCenter + qWidth/2;
+printf("<A HREF=\"hgTracks?db=%s&position=%s:%d-%d&%s_snake%s=full\" TARGET=\"_blank\">%s:%d-%d</A> link to same window size in query assembly: <B>%s</B></A><BR>\n", otherDb, aliasQName, newQs, newQe,hubName, trackHubSkipHubName(database), aliasQName, newQs, newQe, trackHubSkipHubName(otherDb) );
+printTrackHtml(tdb);
+} 
+
 void genericChainClick(struct sqlConnection *conn, struct trackDb *tdb,
                        char *item, int start, char *otherDb)
 /* Handle click in chain track, at least the basics. */
 {
 boolean doSnake = cartOrTdbBoolean(cart, tdb, "doSnake" , FALSE) && cfgOptionBooleanDefault("canSnake", FALSE);
 
-extern void doSnakeClick(struct trackDb *tdb, char *itemName);
 if (doSnake)
-    return doSnakeClick(tdb, item);
+    return doSnakeChainClick(tdb, item);
 
 struct twoBitFile *otherTbf = getOtherTwoBitUrl(tdb);
 char *thisOrg = hOrganism(database);
 char *otherOrg = NULL;
 struct chain *chain = NULL, *subChain = NULL, *toFree = NULL;
 int chainWinSize;
 double subSetScore = 0.0;
 int qs, qe;
 boolean nullSubset = FALSE;
 boolean otherIsActive = FALSE;
 char *hubUrl = NULL;   // if otherDb is a genark browser
 
 if (hDbIsActive(otherDb))
     otherIsActive = TRUE;
 else