946812f7ebe9bd45e3e3fbaaa3db102e9696a973
braney
  Thu Mar 24 14:21:20 2011 -0700
add support for supertracks in hubs  #3381
diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index 25dea75..d7baeb5 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -174,51 +174,80 @@
 struct sqlConnection *conn = hConnectCentral();
 struct hubConnectStatus *status = hubConnectStatusForId(conn, hubId);
 hDisconnectCentral(&conn);
 if (status == NULL)
     errAbort("The hubId %d was not found", hubId);
 if (!isEmpty(status->errorMessage))
     errAbort("Hub %s at %s has the error: %s", status->shortLabel, 
 	    status->hubUrl, status->errorMessage);
 char hubName[16];
 safef(hubName, sizeof(hubName), "hub_%d", hubId);
 struct trackHub *hub = trackHubOpen(status->hubUrl, hubName);
 hubConnectStatusFree(&status);
 return hub;
 }
 
+static struct trackDb *findSuperTrack(struct trackDb *tdbList, char *trackName)
+/*  discover any supertracks, and if there are some add them 
+ *  to the subtrack list of the supertrack */
+{
+struct trackDb *tdb;
+struct trackDb *p = NULL;
+struct trackDb *next;
+
+for(tdb = tdbList; tdb; tdb = next)
+    {
+    /* save away the next pointer becuase we may detach this node and
+     * add it to its supertrack parent */
+    next = tdb->next;
+    if (tdb->parent != NULL && sameString(trackName, tdb->parent->track))
+	{
+	/* found a supertrack with the right name, add this child */
+	p = tdb->parent;
+	slAddHead(&p->subtracks, tdb);
+	}
+    }
+
+return p;
+}
+
 struct trackDb *hubConnectAddHubForTrackAndFindTdb(char *database, 
 	char *trackName, struct trackDb **pTdbList, struct hash *trackHash)
 /* Go find hub for trackName (which will begin with hub_), and load the tracks
  * for it, appending to end of list and adding to trackHash.  Return the
  * trackDb associated with trackName. This will also fill in the html fields,
  * but just for that track and it's parents. */ 
 {
 int hubId = hubIdFromTrackName(trackName);
 struct trackHub *hub = trackHubFromId(hubId);
 struct trackHubGenome *hubGenome = trackHubFindGenome(hub, database);
 struct trackDb *tdbList = trackHubTracksForGenome(hub, hubGenome);
 tdbList = trackDbLinkUpGenerations(tdbList);
 tdbList = trackDbPolishAfterLinkup(tdbList, database);
 rAddTrackListToHash(trackHash, tdbList, NULL, FALSE);
 if (pTdbList != NULL)
     *pTdbList = slCat(*pTdbList, tdbList);
 struct trackDb *tdb = hashFindVal(trackHash, trackName);
 if (tdb == NULL)
+    // superTracks aren't in the hash... look in tdbList
+    tdb = findSuperTrack(tdbList, trackName);
+
+if (tdb == NULL) 
     errAbort("Can't find track %s in %s", trackName, hub->url);
 
 /* Add html for track and parents. */
+/* Note: this does NOT add the HTML for supertrack kids */
 struct trackDb *parent;
 for (parent = tdb; parent != NULL; parent = parent->parent)
     {
     char *simpleName = hubConnectSkipHubPrefix(tdb->track);
     char *url = trackHubRelativeUrl(hubGenome->trackDbFile, simpleName);
     char buffer[10*1024];
     safef(buffer, sizeof buffer, "%s.html", url);
 
     parent->html = netReadTextFileIfExists(buffer);
     freez(&url);
     }
 trackHubClose(&hub);
 
 return tdb;
 }