NCBI C Toolkit Cross Reference

C/desktop/ingengraph.c


  1 /*   ingengraph.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  6 *
  7 *  This software/database is a "United States Government Work" under the
  8 *  terms of the United States Copyright Act.  It was written as part of
  9 *  the author's official duties as a United States Government employee and
 10 *  thus cannot be copyrighted.  This software/database is freely available
 11 *  to the public for use. The National Library of Medicine and the U.S.
 12 *  Government do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 15 *
 16 *  Although all reasonable efforts have been taken to ensure the accuracy
 17 *  and reliability of the software and data, the NLM and the U.S.
 18 *  Government do not and cannot warrant the performance or results that
 19 *  may be obtained by using this software or data. The NLM and the U.S.
 20 *  Government disclaim all warranties, express or implied, including
 21 *  warranties of performance, merchantability or fitness for any particular
 22 *  purpose.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  ingengraph.c
 27 *
 28 * Author:  Fasika Aklilu
 29 *
 30 * Version Creation Date:   8/8/01
 31 *
 32 * $Revision: 6.8 $
 33 *
 34 * File Description: 
 35 *
 36 * Modifications:  
 37 * --------------------------------------------------------------------------
 38 * Date     Name        Description of modification
 39 * -------  ----------  -----------------------------------------------------
 40 *
 41 *
 42 * ==========================================================================
 43 */
 44 
 45 #include <ingengraph.h>
 46 
 47 
 48 #define ING_MAX_VIEWER_HEIGHT  600
 49 #define SEGMENT_SCALE  2336
 50 #define ARROWS_SCALE   500
 51 #define LABELS_SCALE   100
 52 
 53 Boolean IngfeatDefFilter[FEATDEF_MAX];/* filter parameter for SeqMgrExploreFeatures() */
 54 
 55 Boolean IngfeatDefTrack2[FEATDEF_MAX];/* used by Ing_AddToOverviewPage()  when scale is greater than COMPRESS_SCALE */
 56 
 57 Uint1   IngfeatDefTrack[FEATDEF_MAX];/* track features 1=exists 2=exists and is visible */
 58 
 59 
 60 /*******************************************************************************
 61 
 62         Static Var and Function Declarations
 63 
 64 *******************************************************************************/
 65 typedef struct ing_node {
 66   Int4 row;
 67   Uint4 col;
 68   Boolean build;
 69 } IngNode, PNTR IngNodePtr;
 70 
 71 static void Ing_GetNamesZoomedVal(VieweR vNames,Int4Ptr from, Int4Ptr to,
 72         Int4Ptr scaleX,Int4 MaxLength);
 73 static Uint1 Ing_GetMiscFeatColor(CharPtr str_4);
 74 
 75 
 76 /******************************************************************************
 77 
 78   Function : Ing_InitfeatDefFilter(), Ing_AddStringToSad(), Ing_SearchAli(),Ing_GetAlignColor(), Ing_GetCurrentSegment()
 79  
 80   Purpose :  function to retrieve data for drawing
 81 
 82 *******************************************************************************/
 83 extern void Ing_InitfeatDefFilter(void)
 84 {
 85   MemSet(IngfeatDefFilter,1,sizeof(Boolean)*(FEATDEF_MAX));
 86   IngfeatDefFilter[FEATDEF_COMMENT]=FALSE;
 87   IngfeatDefFilter[FEATDEF_BIOSRC]=FALSE;
 88   IngfeatDefFilter[FEATDEF_PUB]=FALSE;
 89   IngfeatDefFilter[FEATDEF_ORG]=FALSE;
 90  
 91 }
 92 
 93 static Uint1Ptr Ing_GetAlignColor(CharPtr name, Uint1Ptr PNTR pClr)
 94 {
 95   if (StringCmp(name, "Spidey")==0)
 96     return pClr[Ing_SPIDEY];
 97   if (StringCmp(name, "Blast 2 seqs")==0)
 98     return pClr[ALIGN_BLAST2SEQ];
 99   if (StringCmp(name, "Blast")==0)
100     return pClr[ALIGN_BLAST];
101   if (StringCmp(name, "Blast file")==0)
102     return pClr[ALIGN_FILE];
103   return pClr[ALIGN_ANNOT];
104 }
105 
106 static CharPtr PNTR Ing_AddStringToSad(CharPtr PNTR names, SeqAnnotPtr sanp, Int4 index)
107 {
108   Int4    i;
109   CharPtr new_name = NULL;
110   CharPtr name = NULL;
111   CharPtr title = NULL;
112   CharPtr PNTR head = NULL;
113   ValNodePtr desc = NULL;
114   Int4    len;
115 
116   if (sanp->name)
117     new_name=sanp->name;
118   else if (sanp->desc) {
119     desc = sanp->desc;
120     while (desc){
121       if (desc->choice == Annot_descr_name){
122         if (new_name == NULL)
123           new_name=(CharPtr)sanp->desc->data.ptrvalue;
124       }
125       if (desc->choice == Annot_descr_title){
126         if (title == NULL)
127           title = (CharPtr)desc->data.ptrvalue;
128       }
129       desc = desc->next;
130     }
131 
132     if(name != NULL)
133       StringNCpy_0(new_name, name, 20);
134     len = StringLen(new_name);
135     if(title != NULL && len < 19)
136       {
137         StringCat(new_name, ":");
138         ++len;
139         StringNCpy_0(new_name+len, title, 20-len);
140       }
141   }
142   else 
143     return NULL;
144 
145   if (names==NULL){
146     head=(CharPtr PNTR)MemNew(sizeof(CharPtr));
147     *head=new_name;
148     return head;
149   }
150   else {
151     head=(CharPtr PNTR)MemNew(sizeof(CharPtr)*index);
152     for (i=0; i<index-1; i++){
153       head[i]=names[i];
154     }
155     
156     head[index-1]=new_name;
157     MemFree(names);
158     return head;
159   }
160 }
161 
162 static Boolean Ing_shouldIstore(IngTrackAlignsPtr tap, SeqAlignPtr sap)
163 {
164   ValNodePtr vnp_h = NULL;
165   ValNodePtr vnp_s = NULL;
166   SeqAlignPtr sap_s = NULL;
167   SeqAlignPtr sap_h = NULL;
168 
169   if (!tap)
170     return TRUE;
171   
172   vnp_h = tap->hidelist;
173   vnp_s = tap->showlist;
174   while (vnp_h){
175     sap_h = (SeqAlignPtr)vnp_h->data.ptrvalue;
176     if (sap == sap_h)
177       return FALSE;
178     vnp_h = vnp_h->next;
179   }
180   while (vnp_s){
181     sap_s = (SeqAlignPtr)vnp_s->data.ptrvalue;
182     if (sap == sap_s)
183       return FALSE;
184     vnp_s = vnp_s->next;
185   }
186 
187   return TRUE;
188 }
189 
190 extern void Ing_SearchAli(SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
191 {
192 BioseqPtr     bsp=NULL;
193 BioseqSetPtr  bssp=NULL;
194 SeqAnnotPtr   sanp=NULL;
195 SeqAlignPtr   salp=NULL;
196 IngSeqAnnotData * sadp=NULL; 
197 
198 
199  sadp=(IngSeqAnnotData *)mydata;
200  if (IS_Bioseq(sep)) {
201    bsp = (BioseqPtr)sep->data.ptrvalue;
202    sanp = bsp->annot;
203  } else if (IS_Bioseq_set(sep)) {
204    bssp = (BioseqSetPtr)sep->data.ptrvalue;
205    sanp = bssp->annot;
206  } else return;
207  
208 
209  while (sanp != NULL) {
210    if (sanp->type == 2) {/*seqalign*/
211      salp=(SeqAlignPtr)sanp->data;
212      if (Ing_shouldIstore(sadp->tap, salp)){
213        sadp->sindex++;
214        sadp->aln_namelist=Ing_AddStringToSad(sadp->aln_namelist, sanp, sadp->sindex);
215        ValNodeAddPointer(&(sadp->aln_showlist),OBJ_SEQALIGN,(Pointer)salp);
216      }
217    }
218    sanp=sanp->next;
219  }
220 }
221 
222 
223 static SegmenT Ing_GetCurrentSegment(IngPopFeatPtr  pfp)
224 {
225   SegmenT CurrentSeg=NULL;
226 
227   if (!(pfp->nPrims%FEATURE_SEGMENT_MAXSIZE))
228     {
229       if (!(pfp->nLevel2%LEVEL2_MAXNUM)){
230         if (!(pfp->nLevel1%LEVEL1_MAXNUM)){
231           pfp->nLevel1++;
232           pfp->seg1=CreateSegment(pfp->pictMain, pfp->nLevel1, 0);
233         }
234         pfp->nLevel2++;
235         pfp->seg2=CreateSegment(pfp->seg1, pfp->nLevel2, 0);
236       }
237       pfp->nLevel3++;
238       CurrentSeg=CreateSegment(pfp->seg2, pfp->nLevel3, 0);
239       pfp->CurrentSeg=CurrentSeg;
240 /*       pfp->nSegs=1; */
241     }
242   else 
243     CurrentSeg=pfp->CurrentSeg;
244 
245   return CurrentSeg;
246 }
247 
248 /*******************************************************************************
249 
250   Function : Ing_BigEncodeIdxFeat()
251  
252   Purpose :  index data for collision detection
253 
254 *******************************************************************************/
255 extern Uint8 Ing_BigEncodeIdxFeat (Uint4 val1,Uint4 val2)
256 {
257 Uint4 index_g[2];
258         
259         index_g[0]=val1;
260         index_g[1]=val2;
261         
262         return *((Uint8Ptr) index_g);
263         
264 }
265 
266 
267 typedef struct ing_pkg {
268   CharPtr title;
269   Int4    row;
270 } IngPkgData, PNTR IngPkgPtr;
271 
272 /*******************************************************************************
273 
274   Function : Ing_BigDecodeIdxFeat()
275   
276   Purpose : retrieve data from index
277 
278 *******************************************************************************/
279 extern void  Ing_BigDecodeIdxFeat (Uint8 index_g, Uint4Ptr val1, Uint4Ptr val2)
280 {
281 Uint4Ptr  index_g2;
282 
283         index_g2 = (Uint4Ptr) (&index_g);
284         if (val1) *val1 = (Uint4) index_g2 [0];
285         if (val2) *val2 = (Uint4) index_g2 [1];
286 }
287 
288 static IngPkgPtr Ing_EncodeFeatString( Uint4 row, CharPtr title)
289 {
290   IngPkgPtr pkg;
291   
292   pkg = (IngPkgPtr)MemNew(sizeof(IngPkgData));
293   pkg->title = title;
294   pkg->row = row;
295 
296   return pkg;
297 }
298 
299 static void Ing_DecodeFeatString(IngPkgPtr pkg, Uint4Ptr row, CharPtr PNTR title)
300 {
301   *row = pkg->row;
302   *title = pkg->title;
303 }
304 
305 /*******************************************************************************
306 
307   Function : Ing_PopOverviewPage(), Ing_PopOverviewRuler(), Ing_AddToOverViewPage(), Ing_AddToOverviewPict(), Ing_AddAlignsToOverviewPage(), Ing_AddOneAlignToOverviewPage()
308  
309   Purpose :  Top (Overview) viewer drawing functions
310 
311 *******************************************************************************/
312 extern Boolean Ing_PopOverviewRuler(VieweR vRuler1, SegmenT pictRuler1, BioseqPtr bsp, IngGraphData GrData, Int4 from, Int4 to, Uint1Ptr seqbuf, Int4 scaleX)
313 {
314   IngExploreSegs     gpn;
315   Int2               nSegments=0;
316   Boolean            bSegmented = FALSE;
317 
318   gpn.seg=pictRuler1;
319   gpn.viewer=vRuler1;
320   gpn.idx=1;
321   gpn.GrData= &GrData;
322   gpn.left=from;
323   gpn.right=to;
324   gpn.seqbuf=seqbuf;
325   gpn.bShowGC = FALSE;
326   gpn.scaleX = scaleX;
327   gpn.bTop = TRUE;
328   gpn.bRegister = FALSE;
329   gpn.bLabels = FALSE;
330   nSegments=SeqMgrExploreSegments(bsp, (Pointer)&gpn, Ing_ExploreSegments);
331   /*this bioseq doesn't have any segments*/
332   if (nSegments==0){
333     AddAttribute(pictRuler1, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
334     AddRectangle(pictRuler1,0,GrData.SegBoxHeight/2 , to - from + 1, -GrData.SegBoxHeight/2, NO_ARROW, TRUE,  2);
335   }
336   else{
337     bSegmented=TRUE;
338   }
339   Ing_AddRuler(pictRuler1, GrData.SegBoxHeight, from, to, scaleX, 1, TRUE);
340 
341   return bSegmented;
342 }
343 
344 
345 static void Ing_AddOneAlignToOverviewPage(SegmenT seg, SeqAlignPtr sap, Int4 row, Int4 start, Int4 stop)
346 {
347   BioseqPtr bsp=NULL;
348   Uint1     strand;
349   Int4      j;
350   PrimitivE prim;
351 
352     strand=AlnMgr2GetNthStrand(sap, 2);
353   if (strand == Seq_strand_minus)
354     j = -6;
355   else
356     j = 6;
357     prim = AddRectangle(seg, start, (row)*(-20), stop, (row)*(-20)+j, NO_ARROW, FALSE,0);
358     SetPrimitiveIDs(prim, sap->idx.entityID, sap->idx.itemID, OBJ_SEQALIGN, 2);
359 
360 }
361 
362 
363 static Uint4 Ing_AddAlignsToOverviewPage(SegmenT pictTop, SegmenT CurrentSeg, Uint2 nPrims, Uint2 nSegs, SeqEntryPtr sep, SeqAlignPtr sap, Uint4 rowNum, Int4 left, Int4 right, CharPtr name, Uint1Ptr Clr)
364 {
365   SeqAlignPtr    salp=NULL;
366   enumPrimAddOrder oldOrder;
367   Boolean        NewLine=FALSE;
368   Int4           start;
369   Int4           stop;
370   Int4           len;
371   Int4           offset;
372   Char           buf[41]={""};
373   Char           label[41]={""};
374   
375 
376 
377   len=right-left+1;
378   offset=left;
379   if (sap->segtype==SAS_DISC){ 
380     salp=(SeqAlignPtr)sap->segs; 
381   } 
382   else {
383     salp=sap; 
384   } 
385 
386   AddAttribute(CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
387   if (StringHasNoText(name))
388     sprintf(label, "Alignment");
389   else {
390     sprintf(label,  "%s", name);
391   }
392   AddLabel(CurrentSeg, -15, (rowNum)*(-20)+6, label, SMALL_TEXT, 0, UPPER_RIGHT, 0);
393   AddAttribute(CurrentSeg, COLOR_ATT, (Clr?Clr:BLACK_COLOR), 0, 0, 0, 0);
394   AddLine(CurrentSeg, 0, (rowNum)*(-20), len, (rowNum)*(-20), 0, 0);
395   oldOrder=ChangeAddPrimOrder(ADD_TO_HEAD);
396   while(salp){
397     AlnMgr2GetNthSeqRangeInSA(salp, 1, &start, &stop);
398     if (start>right || stop<left){
399       salp=salp->next;
400       continue;
401     }
402     start=MAX(left, start);
403     stop=MIN(right, stop);
404     if (!(nPrims%FEATURE_SEGMENT_MAXSIZE))
405       {
406         CurrentSeg=CreateSegment(pictTop, nSegs, 0);
407         nSegs++;
408         AddAttribute(CurrentSeg, COLOR_ATT, 
409                      (Clr?Clr:BLACK_COLOR), 0, 0, 0, 0);
410       }
411     Ing_AddOneAlignToOverviewPage(CurrentSeg, salp, (Int4)rowNum, start-offset, stop-offset);
412     nPrims++;
413     NewLine=TRUE;
414     salp=salp->next; 
415   }
416   ChangeAddPrimOrder(oldOrder);
417   return rowNum;
418 }
419              
420 typedef struct ingcontext{
421   SeqFeatPtr sfp;
422   Int4       left;
423   Int4       right;
424   Uint1      strand;
425   Uint1      featdeftype;
426   Int4       numivals;
427   Int4Ptr    ivals;
428   Uint2      entityID;
429   Uint4      itemID;
430   CharPtr    name;
431 } IngContext, PNTR IngContextPtr;
432 
433 static void Ing_FreeContext (IngContextPtr context){
434   
435   if (context->numivals > 1)
436     MemFree(context->ivals);
437   MemFree(context);
438 }
439 
440 static void Ing_AddToOverviewPict(SegmenT seg, IngContextPtr context, Int4 start, Int4 stop, Int4 base)
441 {
442   Int4  j;
443   PrimitivE  prim;
444   Int4  left;
445   Int4  right;
446   Int4  offset;
447     
448   if (seg == NULL || context == NULL)
449      return;
450   if (context->strand == Seq_strand_minus)
451     j = -6;
452   else
453     j = 6;
454   
455   offset=start;
456   left=MAX(start, context->left);
457   right=MIN(stop, context->right);
458   prim = AddRectangle(seg, left-offset, base, right-offset, base+j, NO_ARROW, FALSE,0);
459   SetPrimitiveIDs(prim, context->entityID, context->itemID, OBJ_SEQFEAT, 2);
460 
461 }
462 
463 
464 static Uint1 Ing_IsTitleAColor(CharPtr title)
465 {
466   if (StringCmp(title, "red") == 0 ||
467       StringCmp(title, "green") == 0 ||
468       StringCmp(title, "blue")==0 ||
469       StringCmp(title, "cyan") == 0 ||
470       StringCmp(title, "magenta") == 0 ||
471       StringCmp(title, "yellow") == 0 ||
472       StringCmp(title, "grey") == 0 ||
473       StringCmp(title, "purple") == 0 ||
474       StringCmp(title, "black") == 0)
475     return TRUE;
476   else
477     return FALSE;
478 }
479 
480 
481 static Boolean LIBCALLBACK Ing_DrawOverviewPage(IngPopFeatPtr pfp, IngContextPtr context)
482 {
483   ValNodePtr tmp_vnp = NULL;
484   Int4       leftmargin;
485   Int4       rightmargin;
486   Uint4      rowNum, featdeftype;
487   Boolean    bPop=FALSE;
488   Boolean    Visible=FALSE;
489   Uint8      idx;
490   Char       str[60]={""};
491   Int4       pict_len;
492   Int4       offset;
493   Boolean    index_by_fdtype = TRUE;
494   IngPkgPtr  pkg = NULL;
495   CharPtr    title = NULL;
496   SeqFeatPtr sfp = NULL;
497   
498   sfp = context->sfp;
499   if (!pfp || !sfp) return (FALSE);
500 
501   if (context->featdeftype == FEATDEF_misc_feature && 
502       !StringHasNoText(sfp->comment) && 
503       Ing_IsTitleAColor(sfp->title))
504     index_by_fdtype = FALSE;
505 
506   leftmargin=pfp->left;
507   offset=pfp->left;
508   rightmargin=pfp->right;
509   pict_len=rightmargin-leftmargin+1;
510 
511   if (!(pfp->nPrims%FEATURE_SEGMENT_MAXSIZE)){ 
512     pfp->CurrentSeg=CreateSegment(pfp->pictMain, pfp->nLevel1, 0);
513     pfp->nLevel1++;
514   } 
515 
516   AddAttribute(pfp->CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
517 
518   if (index_by_fdtype) 
519     AddAttribute(pfp->CurrentSeg, COLOR_ATT, pfp->pClr[context->featdeftype] , 0, 0, 0, 0);
520   else 
521     AddAttribute(pfp->CurrentSeg, COLOR_ATT, pfp->pClr[Ing_GetMiscFeatColor(sfp->title)] , 0, 0, 0, 0);
522   
523   if (!pfp->PopRowsList){
524     rowNum = 0 ;    
525     if (index_by_fdtype){
526       idx=Ing_BigEncodeIdxFeat(rowNum, context->featdeftype);
527       pfp->vnp_last = ValNodeAddBigInt (&pfp->PopRowsList, OBJ_SEQANNOT, idx);
528       pfp->PopRowsList->data.ptrvalue = NULL;
529     }
530     else {
531       pkg = Ing_EncodeFeatString(rowNum, sfp->title);
532       pfp->vnp_last = ValNodeAddPointer(&pfp->PopRowsList, OBJ_SEQFEAT, pkg);
533     }
534     bPop=FALSE;
535   }
536   else{
537     tmp_vnp = pfp->PopRowsList;
538     while(tmp_vnp){
539       if (tmp_vnp->choice == OBJ_SEQANNOT){
540         Ing_BigDecodeIdxFeat((Uint8)tmp_vnp->data.bigintvalue, &rowNum, &featdeftype);
541         if (context->featdeftype == featdeftype){
542           bPop = TRUE;
543           break;
544         }
545       }
546       else {
547         Ing_DecodeFeatString(tmp_vnp->data.ptrvalue, &rowNum, &title);
548         if (StringCmp(sfp->title, title) == 0){
549           bPop = TRUE;
550           break;
551         }
552       }
553       tmp_vnp = tmp_vnp->next;
554     }
555    }
556    
557    
558    if (bPop==FALSE){
559      rowNum = pfp->nPopRows;
560      if (index_by_fdtype){
561        idx = Ing_BigEncodeIdxFeat(rowNum,context->featdeftype);
562        pfp->vnp_last = ValNodeAddBigInt (&pfp->vnp_last, OBJ_SEQANNOT, idx);
563      }
564      else {
565        pkg = Ing_EncodeFeatString(rowNum, sfp->title);
566        pfp->vnp_last = ValNodeAddPointer(&pfp->vnp_last, OBJ_SEQFEAT, (Pointer)pkg);
567      }
568 
569      pfp->nPopRows++;
570      FeatDefLabel(sfp, str, sizeof(str)-1, OM_LABEL_TYPE);
571      if (Ing_IsTitleAColor(sfp->title) && sfp->comment)
572        StringCat(str, sfp->comment);
573      AddLabel(pfp->pictMain, -15, (rowNum)*(-20)+6, str, SMALL_TEXT, 0, UPPER_RIGHT, 0);
574      AddLine(pfp->CurrentSeg, 0, (rowNum)*(-20), pict_len, (rowNum)*(-20), 0, 0);
575      pfp->nPopRows++;
576    }
577    Ing_AddToOverviewPict(pfp->CurrentSeg, context, leftmargin, rightmargin, rowNum*(-20));
578    
579    pfp->nPrims++;
580    return (TRUE);
581 }
582 
583 static int LIBCALLBACK Ing_SortByChoice (VoidPtr ptr1, VoidPtr ptr2)
584 {
585   ValNodePtr  vnp1;
586   ValNodePtr  vnp2;
587 
588   if (ptr1 == NULL || ptr2 == NULL) return 0;
589   vnp1 = *((ValNodePtr PNTR) ptr1);
590   vnp2 = *((ValNodePtr PNTR) ptr2);
591   if (vnp1 == NULL || vnp2 == NULL) return 0;
592 
593   if (vnp1->choice > vnp2->choice) {
594     return 1;
595   } else if (vnp1->choice < vnp2->choice) {
596     return -1;
597   }
598 
599   return 0;
600 }
601 
602 static Boolean LIBCALLBACK Ing_CollectFeatures1(SeqFeatPtr sfp, SeqMgrFeatContextPtr sfc)
603 {
604   IngPopFeatPtr pfp = NULL;
605   IngContextPtr context = NULL;
606   Int4          feat_len;
607   Boolean       index_by_fdtype = TRUE;
608   Int4          scaledLen;
609   Int4          scale;
610 
611   pfp = (IngPopFeatPtr)sfc->userdata;
612   if (!pfp) return (FALSE);
613   
614   if (sfc->featdeftype == FEATDEF_misc_feature && 
615       !StringHasNoText(sfp->comment) && 
616       Ing_IsTitleAColor(sfp->title))
617     index_by_fdtype = FALSE;
618   
619   feat_len=sfc->right-sfc->left;
620   scale=pfp->scaleX;
621   if (scale>COMPRESS_SCALE){ 
622     scaledLen=feat_len/scale; 
623     if (index_by_fdtype){
624       if (scaledLen<2 && IngfeatDefTrack2[sfc->featdeftype]) 
625         return (TRUE); 
626       else 
627         IngfeatDefTrack2[sfc->featdeftype]=TRUE; 
628     } 
629   }
630 
631   context = (IngContextPtr)MemNew(sizeof(IngContext));
632   context->left = sfc->left;
633   context->right = sfc->right;
634   context->featdeftype = sfc->featdeftype;
635   context->sfp = sfc->sfp;
636   context->strand = sfc->strand;
637   context->entityID = sfc->entityID;
638   context->itemID = sfc->itemID;
639 
640   if (!pfp->group1)
641     pfp->group1_last = ValNodeAddPointer(&pfp->group1, sfc->featdeftype, (Pointer)context);
642   else
643     pfp->group1_last = ValNodeAddPointer(&pfp->group1_last, sfc->featdeftype, (Pointer)context);
644 
645   return (TRUE);
646 }
647 
648 static Boolean LIBCALLBACK Ing_CollectFeatures2(SeqFeatPtr sfp, SeqMgrFeatContextPtr sfc)
649 {
650   IngPopFeatPtr pfp = NULL;
651   IngContextPtr context = NULL;
652   Int4          numivals = 0, i;
653 
654   pfp = (IngPopFeatPtr)sfc->userdata;
655   if (!pfp) return (FALSE);
656   
657   IngfeatDefTrack[sfc->featdeftype] = 2;
658 
659   context = (IngContextPtr)MemNew(sizeof(IngContext));
660   context->left = sfc->left;
661   context->right = sfc->right;
662   context->featdeftype = sfc->featdeftype;
663   context->sfp = sfc->sfp;
664   context->strand = sfc->strand;
665   context->entityID = sfc->entityID;
666   context->itemID = sfc->itemID;
667 
668   numivals = sfc->numivals;
669   if (numivals > 1){
670     context->ivals = (Int4Ptr)MemNew(sizeof(Int4)*numivals*2);
671     for (i = 0; i < (numivals*2); i++)
672       context->ivals[i] = sfc->ivals[i];
673     context->numivals = numivals;
674   }
675   else {
676     context->numivals = 0;
677   }
678   
679   if (sfc->sap->name != NULL){ /* feature was read into file */
680     context->name = sfc->sap->name;
681     if (!pfp->group3)
682       pfp->group3_last = ValNodeAddPointer(&pfp->group3, sfc->featdeftype, (Pointer)context);
683     else
684       pfp->group3_last = ValNodeAddPointer(&pfp->group3_last, sfc->featdeftype, (Pointer)context);
685   }
686   else if (sfc->featdeftype < 7){
687     if (!pfp->group1)
688       pfp->group1_last = ValNodeAddPointer(&pfp->group1, sfc->featdeftype, (Pointer)context);
689     else
690       pfp->group1_last = ValNodeAddPointer(&pfp->group1_last, sfc->featdeftype, (Pointer)context);
691   }
692   else {
693     if (!pfp->group2)
694       pfp->group2_last = ValNodeAddPointer(&pfp->group2, sfc->featdeftype, (Pointer)context);
695     else
696       pfp->group2_last = ValNodeAddPointer(&pfp->group2_last, sfc->featdeftype, (Pointer)context);
697   }
698   return (TRUE);
699 }
700 
701 
702 extern Uint4 Ing_PopOverviewPage(BioseqPtr bsp, SegmenT pictTop, Int4 left, Int4 right, Uint1Ptr PNTR pClr, Int4 maxScaleX, IngTrackAlignsPtr tap)
703 {
704   IngPopFeat   pf;
705   Uint2        entityID;
706   Int4         i;
707   SeqEntryPtr  sep;
708   SeqAnnotPtr  sanp=NULL;
709   SeqAlignPtr  sap=NULL;
710   SeqLocPtr    slp=NULL, whole_slp=NULL;
711   Uint4        nPopRows=0;
712   IngSeqAnnotData  sad;
713   SegmenT      CurrentSeg;
714   Char         buf[50]={""};
715   Int4         margin, len;
716   Int4         start=0;
717   ValNodePtr   slp_list=NULL, slp_head=NULL;
718   ValNodePtr   slp_cur = NULL;
719   ValNodePtr   vnp = NULL;
720   Uint1Ptr     Clr=NULL;
721   CharPtr PNTR names = NULL;
722   Boolean      bUpdate = FALSE;
723   IngContextPtr context = NULL;
724  
725 
726   whole_slp=SeqLocIntNew(left, right, Seq_strand_plus, (SeqIdPtr)bsp->id);
727 
728   if (maxScaleX>COMPRESS_SCALE){
729     start=left;
730     len=right;
731     while (start < len){
732       slp=SeqLocIntNew(start, start+maxScaleX, Seq_strand_plus, (SeqIdPtr)bsp->id);
733       if (slp_list == NULL)
734         slp_cur = ValNodeAddPointer(&slp_list, OBJ_BIOSEQ, (Pointer)slp);
735       else 
736         slp_cur = ValNodeAddPointer(&slp_cur, OBJ_BIOSEQ, (Pointer)slp);
737       start+=maxScaleX;
738     }
739     slp=SeqLocIntNew(start, len-1, Seq_strand_plus, (SeqIdPtr)bsp->id);
740     if (slp_list == NULL)
741       ValNodeAddPointer(&slp_list, OBJ_BIOSEQ, (Pointer)slp);
742     else      
743       ValNodeAddPointer(&slp_cur, OBJ_BIOSEQ, (Pointer)slp);
744 
745     MemSet(&pf,0,sizeof(pf));
746     pf.pictMain=pictTop;
747     pf.pClr=pClr;
748     pf.scaleX=maxScaleX;
749     pf.nPrims=0;
750     pf.nLevel1=1;
751     pf.left=left;
752     pf.right=right;
753     pf.group1 = NULL;
754     pf.group1_last = NULL;
755     pf.PopRowsList=NULL;
756     pf.vnp_last = NULL;
757     slp_head=slp_list;
758     while(slp_list){
759       slp=slp_list->data.ptrvalue;
760       MemSet((Pointer)IngfeatDefTrack2, 0, sizeof(IngfeatDefTrack2));
761       SeqMgrExploreFeatures (bsp, (Pointer) &pf, Ing_CollectFeatures2, slp, NULL,IngfeatDefFilter);
762       slp_list=slp_list->next;
763       SeqLocFree(slp);
764     }
765     ValNodeFree(slp_head); 
766   }
767   else {
768     MemSet(&pf,0,sizeof(pf));
769     pf.pictMain=pictTop;
770     pf.pClr=pClr;
771     pf.scaleX=maxScaleX;
772     pf.nPrims=0;
773     pf.nLevel1=1;
774     pf.left=left;
775     pf.right=right;
776     pf.PopRowsList=NULL;
777     pf.group1 = NULL;
778     pf.group1_last = NULL;
779     pf.group2 = NULL;
780     pf.group2_last = NULL;
781     pf.group3 = NULL;
782     pf.group3_last = NULL;
783     SeqMgrExploreFeatures (bsp, (Pointer) &pf,Ing_CollectFeatures2, whole_slp, NULL,IngfeatDefFilter);
784   }
785 /*   vnp = ValNodeSort(pf.group1, Ing_SortByChoice); */
786 
787   if (pf.group1) {
788      for (vnp = pf.group1; vnp != NULL; vnp = vnp->next){
789        context = (IngContextPtr)vnp->data.ptrvalue;
790        Ing_DrawOverviewPage(&pf, context);
791        Ing_FreeContext(context);
792      }
793      ValNodeFree (pf.group1);
794      pf.group1 = NULL;
795      pf.group1_last = NULL;
796    }
797    if (pf.group2){
798      for (vnp = pf.group2; vnp != NULL; vnp = vnp->next){
799        context = (IngContextPtr)vnp->data.ptrvalue;
800        Ing_DrawOverviewPage(&pf, context);
801        Ing_FreeContext(context);
802      }
803      ValNodeFree (pf.group2);
804      pf.group2 = NULL;
805      pf.group2_last = NULL;
806    }
807    if (pf.group3){
808      for (vnp = pf.group3; vnp != NULL; vnp = vnp->next){
809        context = (IngContextPtr)vnp->data.ptrvalue;
810        Ing_DrawOverviewPage(&pf, context);
811        Ing_FreeContext(context);
812      }
813      ValNodeFree(pf.group3);
814      pf.group3 = NULL;
815      pf.group3_last = NULL;
816    }
817    if (pf.PopRowsList) ValNodeFree(pf.PopRowsList);
818    pf.PopRowsList = NULL;
819 
820   nPopRows = pf.nPopRows;
821   pf.nLevel1++;
822   CurrentSeg=CreateSegment(pictTop, pf.nLevel1, 0);
823   if (IngfeatDefFilter[0]){ 
824     entityID=ObjMgrGetEntityIDForPointer(bsp); 
825     sep = GetTopSeqEntryForEntityID(entityID); 
826     if (tap && tap->update){
827       sad.sindex= tap->showindex;
828       sad.hindex= tap->hideindex;
829       sad.aln_showlist = tap->showlist;
830       sad.aln_namelist = tap->namelist;
831       sad.aln_hidelist = tap->hidelist;
832       sad.aln_hnamelist = tap->hnamelist;
833       bUpdate = TRUE;
834     }
835     else if (!tap){
836       sad.sindex = 0;
837       sad.hindex= 0;
838       sad.aln_showlist = NULL;
839       sad.aln_namelist = NULL;
840       sad.aln_hidelist = NULL;
841       sad.aln_hnamelist = NULL;
842       bUpdate = TRUE;
843     }
844     if (bUpdate){
845       sad.tap = tap;
846       SeqEntryExplore(sep,(Pointer)&sad, Ing_SearchAli);
847       if (tap){
848         tap->namelist = sad.aln_namelist;
849         tap->showlist = sad.aln_showlist;
850         tap->hidelist = sad.aln_hidelist;
851         tap->hnamelist = sad.aln_hnamelist;
852         tap->showindex = sad.sindex;
853         tap->hideindex = sad.hindex;
854         tap->update = FALSE;
855       }
856       vnp = sad.aln_showlist;
857       names = sad.aln_namelist;
858       
859     }
860     else {
861       vnp = tap->showlist;
862       names = tap->namelist;
863     }
864       
865     if (!vnp) goto end;
866     IngfeatDefTrack[0]=2;
867     i=0;
868     len=right-left+1;
869     margin=10*maxScaleX;
870     while (vnp){
871        sap=(SeqAlignPtr)vnp->data.ptrvalue;
872        if (sap->segtype!=SAS_DISC && StringCmp(names[i], "Spidey")==0)
873          goto skipindex;
874        AMAlignIndexFreeEitherIndex(sap);
875        AlnMgr2IndexLite(sap);
876        AlnMgr2SortAlnSetByNthRowPos(sap, 1);
877         
878      skipindex:
879        AssignIDsInEntity(entityID, OBJ_SEQALIGN, (Pointer)sap);
880        Clr=Ing_GetAlignColor(names[i], pClr);
881        nPopRows=Ing_AddAlignsToOverviewPage(pictTop, CurrentSeg, 0, pf.nLevel1, sep, sap, nPopRows, left, right, names[i], Clr);
882        vnp=vnp->next;
883        nPopRows+=2;
884        i++;
885      }
886    } 
887 
888  end:
889   SeqLocFree(whole_slp);
890   return (nPopRows);
891 }
892 
893 
894 
895 /*******************************************************************************
896 
897   Function : Ing_PopDetailedPage(), Ing_AddToDetailedPage(), Ing_AddToDetailedPict(), Ing_AddAlignsToDetailedPage(), Ing_AddOneAlignToDetailedPage()
898  
899   Purpose :  Bottom (Detailed) viewer drawing functions
900 
901 *******************************************************************************/
902 
903 static void Ing_AddOneAlignToDetailedPage(SegmenT seg, SeqAlignPtr sap, Int4 row, Int4 start, Int4 stop, Int4 offset, Int4 scale, Uint2 alignID)
904 {
905    Uint1     strand;
906   Int4      i=0;
907   PrimitivE prim;
908   Int4      numivals;
909   AlnMsg2Ptr amp1 = NULL;
910   AlnMsg2Ptr amp2 = NULL;
911   SegmenT   subSeg;
912   Boolean   more;
913   Uint1     ARROW=NO_ARROW;
914   Int4      half;
915 
916  
917   half = Ing_FEAT_HEIGHT/2;
918   strand=AlnMgr2GetNthStrand(sap, 2);
919   numivals= AlnMgr2GetNumSegs(sap);
920   if (numivals>1){
921     subSeg=CreateSegment(seg, alignID, 0);
922     amp1 = AlnMsgNew2();
923     amp2 = AlnMsgNew2();
924     amp1->from_aln = 0;
925     amp1->to_aln = -1;
926     amp1->row_num = 1;
927     amp2->from_aln = 0;
928     amp2->to_aln = -1; 
929     amp2->row_num = 2;
930     i=1;
931     while((Boolean) (more = AlnMgr2GetNextAlnBit(sap, amp2))){
932       AlnMgr2GetNextAlnBit(sap, amp1);
933       if (amp2->type == AM_SEQ){
934         if (scale<ARROWS_SCALE){
935           if (strand==Seq_strand_minus && i==1)
936             ARROW=LEFT_ARROW;
937           else if (strand==Seq_strand_plus && i==numivals)
938             ARROW=RIGHT_ARROW;
939           else
940             ARROW=NO_ARROW;
941         }
942         else {
943           ARROW = NO_ARROW;
944         }
945         if (amp1->from_row>stop || amp1->to_row<start){
946           i++;
947           continue;
948         } 
949         prim = AddRectangle(subSeg, MAX(start, amp1->from_row)-offset, (row)*(-20), MIN(stop, amp1->to_row)-offset, (row)*(-20)-Ing_FEAT_HEIGHT, ARROW, TRUE,0);
950         SetPrimitiveIDs(prim, sap->idx.entityID, sap->idx.itemID, OBJ_SEQALIGN, 0);
951       }
952       i++;
953     }
954     AlnMsgFree2(amp1);
955     AlnMsgFree2(amp2);
956     AddLine(subSeg, start-offset, (row)*(-20)-half, stop-offset, (row)*(-20)-half, 0, 0);
957   }
958   else {
959     if (scale<ARROWS_SCALE){
960       prim = AddRectangle(seg, start-offset, (row)*(-20), stop-offset, (row)*(-20)-Ing_FEAT_HEIGHT, (strand==Seq_strand_minus?LEFT_ARROW:RIGHT_ARROW), TRUE, 0);
961     }
962     else {
963       prim= AddRectangle(seg, start-offset, (row)*(-20), stop-offset, (row)*(-20)-2, NO_ARROW, TRUE, 0);
964     }
965     SetPrimitiveIDs(prim, sap->idx.entityID, sap->idx.itemID, OBJ_SEQALIGN, alignID);
966   }
967   
968 }
969 
970 static Uint4 Ing_NextExon(Uint4 exon, Uint1 strand)
971 {
972   if (strand==Seq_strand_plus)
973     exon++;
974   else
975     exon--;
976 
977   return exon;
978 }
979 
980 /*
981 typedef struct ing_rowdata{
982   Int4 index;
983   Int4 start_row;
984   Int4Ptr cols;
985 }IngRowData, PNTR IngRowDataPtr;
986 
987 static IngRowDataPtr rdp = NULL;
988 
989 
990 static Boolean Ing_WhichRow(Int4 from, Int4 to, Uint4Ptr rowp)
991 {
992   Int4 i, index;
993   Int4Ptr cols, tmp;
994 
995   if (!rdp) return -1;
996   index = rdp->index + 1;
997   cols = rdp->cols;
998 
999   for (i = 0; i < index; i++){
1000     if (cols[i] < from){
1001       cols[i] = to;
1002       *rowp = (Uint4)rdp->start_row + i;
1003       return (TRUE);
1004     }
1005   }
1006   
1007   tmp = (Int4Ptr)MemNew(sizeof(Int4)*index+1);
1008   for (i = 0; i < index; i++){
1009     tmp[i] = cols[i];
1010   }
1011   tmp[index] = to;
1012   rdp->cols = tmp;
1013   rdp->index++;
1014   MemFree(cols);
1015 
1016   return (FALSE);
1017 }
1018 */
1019 
1020 static Uint4 Ing_AddAlignsToDetailedPage(SegmenT pictBottom, IngPopFeatPtr pfp, SeqEntryPtr sep, SeqAlignPtr sap, Uint4 rowNum, Int4 left, Int4 right, Uint1Ptr Clr, Uint4 scaleX, CharPtr name, Uint2 alignID, Boolean isExons)
1021 {
1022   Char             buf[41]={""};
1023   Char             label[41]={""};
1024   Uint4            top, bottom;
1025   enumPrimAddOrder oldOrder;
1026   SeqIdPtr         sip=NULL;
1027   Uint8            idx;
1028   Boolean          NewLine=FALSE;
1029   Uint4            rowCnt=0;
1030   Uint4            ColStart;
1031   Int4             start, stop;
1032   Int4             i;
1033   AMAlignIndex2Ptr  amaip=NULL;
1034   Int4             len;
1035   Int4             len_diff;
1036   Int4             bExonlabels=FALSE;
1037   Int4             label_len;
1038   Int4             feat_len;
1039   Boolean          labels=TRUE;
1040   Boolean          bDraw = FALSE;
1041   Boolean          bOver_the_edge = FALSE;
1042   Boolean          bSaved = FALSE, bTrim = FALSE;
1043   Int4             offset;
1044   Uint4            exon=0;
1045   Uint1            strand=0;
1046   SegmenT          CurrentSeg=NULL;
1047   ValNodePtr       vnp_head = NULL;
1048   ValNodePtr       tmp_vnp = NULL;
1049   ValNodePtr       vnp_half = NULL;
1050   ValNodePtr       vnp_cur = NULL;
1051 
1052 
1053   amaip = (AMAlignIndex2Ptr)(sap->saip);
1054   if (!amaip) return rowNum; 
1055   len=right-left+1;
1056   offset=left;
1057 
1058   if ((StringCmp(name, "Spidey")==0) && isExons){
1059     bExonlabels=TRUE;
1060     strand=AlnMgr2GetNthStrand(amaip->saps[0], 2);
1061     if (strand==Seq_strand_minus)
1062       exon=amaip->numsaps;
1063     else  
1064       exon=1;
1065   }
1066 
1067   if (scaleX > LABELS_SCALE)
1068     labels=FALSE;
1069   oldOrder=ChangeAddPrimOrder(ADD_TO_HEAD);
1070   top=(rowNum)*(-20);
1071   rowNum++;
1072   rowCnt=rowNum;
1073 
1074   for(i=0; i<amaip->numsaps; i++){
1075     AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], 1, &start, &stop);
1076     if (start>right || stop<left)
1077       continue;
1078 
1079     CurrentSeg = Ing_GetCurrentSegment(pfp);
1080     if (!CurrentSeg) return (FALSE);
1081     start=MAX(start, left);
1082     stop=MIN(stop, right);
1083     if (labels && pfp->showLabels) {
1084 /*       SetSmallFont(); */
1085       if (bExonlabels){
1086         sprintf(label, "Exon %u", exon);
1087         exon = Ing_NextExon(exon, strand);
1088       }
1089       else {
1090         sip=AlnMgr2GetNthSeqIdPtr(amaip->saps[i], 2);
1091         SeqIdWrite(sip, buf, PRINTID_REPORT, 41);
1092         sprintf(label,"gi|%s", buf);
1093       }
1094       label_len=(StringWidth(label)+2)*scaleX;
1095       feat_len=stop-start-1;
1096       if (feat_len<label_len){
1097       if ((start - offset - (label_len - feat_len)/2)<0)
1098         bOver_the_edge = TRUE;
1099         if (bOver_the_edge)
1100           len_diff = ((label_len-feat_len)+scaleX);
1101         else
1102           len_diff= ((label_len-feat_len)/2)+(1*scaleX);
1103       }
1104       else
1105         len_diff=1*scaleX;
1106     }
1107     else{
1108       len_diff=1*scaleX;
1109     }
1110 
1111     if (!vnp_head){
1112       ColStart=stop+len_diff;
1113       idx=Ing_BigEncodeIdxFeat(rowCnt, ColStart);
1114       vnp_cur=ValNodeAddBigInt(&vnp_head, 5, idx);
1115       NewLine=FALSE;
1116     }
1117     else{
1118       tmp_vnp=vnp_head;
1119       while(tmp_vnp){
1120         Ing_BigDecodeIdxFeat((Uint8)tmp_vnp->data.bigintvalue, &rowCnt, &ColStart);
1121         if (ColStart < (Uint4) (MAX(0, start-len_diff))){
1122           ColStart=stop+len_diff;
1123           tmp_vnp->data.bigintvalue=Ing_BigEncodeIdxFeat(rowCnt,ColStart);
1124           NewLine=FALSE;
1125           break;
1126         }
1127         tmp_vnp=tmp_vnp->next;
1128       }
1129     }
1130     if (NewLine){
1131       rowNum++;
1132       ColStart=stop+len_diff;
1133       idx=Ing_BigEncodeIdxFeat(rowNum, ColStart);
1134       vnp_cur = ValNodeAddBigInt(&vnp_cur, 5, idx);
1135     /* start triming list(#rows) if it grows beyond 100 */
1136       if (!(rowCnt % 10)){ 
1137         if (!(rowCnt % 120))
1138           bTrim = TRUE;
1139         
1140         if (!bSaved){
1141           vnp_half = vnp_cur;
1142           bSaved = TRUE;
1143         }
1144         else if (bTrim){
1145           vnp_half->next = NULL;
1146           ValNodeFree(vnp_head);
1147           vnp_head = vnp_cur;
1148           bSaved = FALSE;
1149         }
1150       }
1151       rowCnt=rowNum;
1152     }
1153 
1154     if (labels && pfp->showLabels){
1155       AddAttribute(CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1156       if (bOver_the_edge)
1157         AddLabel(CurrentSeg, start - offset, rowCnt*(-20), label, SMALL_TEXT, 0, UPPER_RIGHT, 0);
1158       else 
1159         AddLabel (CurrentSeg, start - offset + (stop-start)/2, rowCnt*(-20), label, SMALL_TEXT, 0,  UPPER_CENTER, 0); 
1160     }
1161     AddAttribute(CurrentSeg, COLOR_ATT, Clr, 0, 0, 0, 0);
1162     Ing_AddOneAlignToDetailedPage(CurrentSeg, amaip->saps[i], (Int4)rowCnt, start, stop, offset, scaleX, alignID);
1163     pfp->nPrims++;
1164     NewLine = TRUE;
1165     bDraw = TRUE;
1166   }
1167 
1168   if (bDraw){
1169     CurrentSeg = Ing_GetCurrentSegment(pfp);
1170     if (!CurrentSeg) return (FALSE);
1171     
1172     AddAttribute(CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1173     if (StringHasNoText(name))
1174       sprintf(label, "Alignment");
1175     else {
1176       sprintf(label,  "%s", name);
1177     }
1178     AddAttribute(CurrentSeg, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
1179     AddLabel(CurrentSeg, (len/2)+(10*scaleX), top+6, label, SMALL_TEXT, 0, UPPER_CENTER, 0);
1180     
1181     rowNum++;
1182     bottom=(rowNum)*(-20);
1183     AddAttribute(CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1184     AddRectangle(CurrentSeg, (-10)*scaleX, top, len+(10*scaleX), bottom, NO_ARROW, FALSE,0);
1185     ChangeAddPrimOrder(oldOrder);
1186   }
1187   else {
1188     rowNum-=3;
1189   }
1190 
1191   return rowNum;
1192 }
1193 
1194 
1195 static void Ing_AddToDetailedPict(SegmenT Seg, IngContextPtr context, Int4 yBase, Uint4Ptr subSegID, Int4 start, Int4 stop, Int4 scale)
1196 {
1197   PrimitivE  prim;
1198   Int4       left_end, right_end;
1199   Uint1      strand;
1200   Int4       fhalf;
1201   Int4       numivals, max, i;
1202   Int4       left, right;
1203   Int4Ptr    ivals;
1204   SegmenT    subSeg;
1205   SeqFeatPtr sfp;
1206   Uint1      ARROW=NO_ARROW;
1207   Int4       offset;
1208 
1209   if (Seg == NULL || context == NULL)
1210      return;
1211   
1212   fhalf=Ing_FEAT_HEIGHT/2;
1213   strand=context->strand;
1214   offset=start;
1215   left=MAX(start, context->left);
1216   right=MIN(stop, context->right);
1217   
1218   ivals=context->ivals;
1219   numivals=context->numivals;
1220   
1221   if (numivals>1){
1222     subSeg=CreateSegment(Seg, *subSegID, 0);
1223     (*subSegID)++;
1224     sfp=(SeqFeatPtr)context->sfp;
1225     /* draw a line thought segmented feature */
1226     left_end=(strand == Seq_strand_minus ? ivals[2*numivals-1] : ivals[0]);
1227     right_end=(strand == Seq_strand_minus ? ivals[0] : ivals[2*numivals-1]);
1228     if (!(right_end < offset)){
1229       left_end=MAX(left_end, offset);
1230       prim=AddLine(subSeg, left_end-offset, yBase-fhalf, right_end-offset, yBase-fhalf, FALSE, 0);
1231       SetPrimitiveIDs(prim, context->entityID, context->itemID, sfp->idx.itemtype, 0);
1232     }
1233       /* far left ivals */
1234     left_end=(strand == Seq_strand_minus ? ivals[2*numivals-1] : ivals[0]); 
1235     right_end=(strand == Seq_strand_minus ? ivals[2*numivals-2] : ivals[1]);
1236     if (!(right_end < offset)){
1237       left_end=MAX(left_end, offset);
1238       if (scale < ARROWS_SCALE){
1239         ARROW = (strand == Seq_strand_minus)?LEFT_ARROW:NO_ARROW;
1240       }
1241       else {
1242         ARROW = NO_ARROW;
1243       }
1244       prim = AddRectangle(subSeg, left_end-offset, yBase, right_end-offset, yBase-Ing_FEAT_HEIGHT, ARROW, TRUE, 0);  
1245       SetPrimitiveIDs(prim, context->entityID, context->itemID, sfp->idx.itemtype, 0);
1246     }
1247     /* middle ivals */
1248     if (numivals>2){
1249       if (strand==Seq_strand_minus){
1250         for (i = 2*numivals-4 ; i > 1 ; i -= 2){
1251           left_end=MIN(ivals[i], ivals[i+1]);
1252           right_end=MAX(ivals[i], ivals[i+1]);
1253           if ((!(left_end<offset && right_end<offset))&&(!(left_end>stop && right_end>stop))){
1254             prim = AddRectangle(subSeg,MAX(start, left_end)-offset, yBase, MIN(stop, right_end)-offset,yBase-Ing_FEAT_HEIGHT,NO_ARROW,TRUE,0);
1255             SetPrimitiveIDs(prim, context->entityID, context->itemID, sfp->idx.itemtype, 0);
1256           }
1257           
1258         }
1259       }
1260       else{
1261         max=2*numivals-2;
1262         for (i = 2 ; i < max ; i += 2){
1263           left_end=MIN(ivals[i], ivals[i+1]);
1264           right_end=MAX(ivals[i], ivals[i+1]);
1265           if ((!(left_end<offset && right_end<offset)) && 
1266               (!(left_end>stop && right_end>stop))){
1267           prim = AddRectangle(subSeg, MAX(start, left_end)-offset,yBase, MIN(stop, right_end)-offset, yBase-Ing_FEAT_HEIGHT, NO_ARROW, TRUE, 0);
1268           SetPrimitiveIDs(prim, context->entityID, context->itemID, sfp->idx.itemtype, 0);
1269           }
1270         }
1271       }               
1272     }
1273     /* far right ivals*/
1274     left_end=(strand == Seq_strand_minus ? ivals[0] : ivals[2*numivals-2]);
1275     right_end=(strand == Seq_strand_minus ?ivals[1] : ivals[2*numivals-1]);
1276     if (!(left_end>right && right_end>right)){
1277       if (scale < ARROWS_SCALE){
1278         ARROW = (strand == Seq_strand_minus)?NO_ARROW:RIGHT_ARROW;
1279       }
1280       else {
1281         ARROW = NO_ARROW;
1282       }
1283       prim = AddRectangle(subSeg, MAX(start, left_end)-offset, yBase, MIN(stop, right_end)-offset, yBase-Ing_FEAT_HEIGHT,  ARROW, TRUE, 0);
1284       SetPrimitiveIDs(prim, context->entityID, context->itemID, sfp->idx.itemtype, 0);
1285     }
1286   }
1287   else {
1288     if (scale < ARROWS_SCALE){
1289       prim = AddRectangle(Seg, left-offset, yBase, right-offset, yBase-Ing_FEAT_HEIGHT, (strand == Seq_strand_minus ?LEFT_ARROW:RIGHT_ARROW), TRUE, 0);
1290     }
1291     else {
1292       prim= AddRectangle(Seg, left-offset, yBase, right-offset, yBase-2, NO_ARROW, TRUE, 0);
1293     }
1294 
1295     SetPrimitiveIDs(prim, context->entityID, context->itemID, OBJ_SEQFEAT, OBJ_SEQFEAT);
1296   }
1297 }
1298 
1299 
1300 static void Ing_DrawDetailedPage(IngPopFeatPtr pfp, IngContextPtr context)
1301 {
1302   ValNodePtr tmp_vnp = NULL;
1303   Int4       leftmargin;
1304   Int4       rightmargin;
1305   Int4       left;
1306   Int4       right;
1307   Uint4      rowNum;
1308   Boolean    bPop=FALSE;
1309   Uint8      idx;
1310   Uint4       ColStart;
1311   Char       str[60]={""};
1312   Int4       scaleX;
1313   Int4       label_len, len_diff;
1314   Int4       feat_len;
1315   Boolean    labels=TRUE;
1316   Boolean    over_the_edge=FALSE;
1317   SegmenT    CurrentSeg=NULL;
1318   SeqFeatPtr sfp = NULL;
1319 
1320  
1321   sfp = context->sfp;
1322   if (!pfp || !sfp) return;
1323   
1324   scaleX=pfp->scaleX;
1325   leftmargin=pfp->left;
1326   rightmargin=pfp->right;
1327   left=MAX(leftmargin, context->left);
1328   right=MIN(rightmargin, context->right);
1329   feat_len=right-left;
1330   if (scaleX>LABELS_SCALE){ 
1331     labels=FALSE; 
1332    }
1333   if (labels && pfp->showLabels){
1334     FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_CONTENT);
1335     label_len=(StringWidth(str))*scaleX;
1336     if (label_len > feat_len){
1337       if ((left - (label_len - feat_len)/2)<0)
1338         over_the_edge = TRUE;
1339       if (over_the_edge)
1340         len_diff = ((label_len - feat_len)+scaleX);
1341       else 
1342         len_diff= ((label_len-feat_len)/2)+(1*scaleX);
1343     }
1344     else
1345       len_diff=1*scaleX;
1346   }
1347   else{
1348     len_diff=1*scaleX;
1349   }
1350 
1351   CurrentSeg=Ing_GetCurrentSegment(pfp);
1352   if (!CurrentSeg) return;
1353 
1354   if (context->featdeftype == FEATDEF_misc_feature &&
1355       !StringHasNoText(sfp->comment) && 
1356       Ing_IsTitleAColor(sfp->title)){
1357     AddAttribute(pfp->CurrentSeg, COLOR_ATT, pfp->pClr[Ing_GetMiscFeatColor(sfp->title)] , 0, 0, 0, 0);
1358   }
1359   else {
1360     AddAttribute(pfp->CurrentSeg, COLOR_ATT, pfp->pClr[context->featdeftype] , 0, 0, 0, 0);
1361   }
1362 
1363  if (!pfp->PopRowsList){
1364     rowNum = pfp->nPopRows;
1365     ColStart=context->right+len_diff;
1366     idx=Ing_BigEncodeIdxFeat(rowNum, ColStart);
1367     pfp->vnp_last = ValNodeAddBigInt (&pfp->PopRowsList, 5, idx);
1368     bPop=TRUE;
1369     pfp->nPopRows++;
1370   }  else{
1371     tmp_vnp=pfp->PopRowsList;
1372     while(tmp_vnp){
1373       Ing_BigDecodeIdxFeat((Uint8)tmp_vnp->data.bigintvalue,&rowNum,&ColStart);
1374       if (ColStart < (Uint4)(MAX(0, left-len_diff))){
1375         ColStart=context->right+len_diff;
1376         tmp_vnp->data.bigintvalue=Ing_BigEncodeIdxFeat(rowNum,ColStart);
1377         bPop=TRUE;
1378         break;
1379         }
1380       tmp_vnp = tmp_vnp->next;
1381     }
1382   }
1383   if (bPop==FALSE){
1384     rowNum = pfp->nPopRows;
1385     ColStart=context->right+len_diff;
1386     idx = Ing_BigEncodeIdxFeat(rowNum, ColStart);
1387     pfp->vnp_last = ValNodeAddBigInt (&pfp->vnp_last, 5, idx);
1388 
1389     /* start triming list(#rows) if it grows beyond 100 */
1390     if (!(rowNum % 10)){ 
1391       if (!(rowNum % 120))
1392         pfp->bTrim = TRUE;
1393 
1394       if (!pfp->bSaved){
1395         pfp->vnp_top10 = pfp->vnp_last;
1396         pfp->bSaved = TRUE;
1397       }
1398       else if (pfp->bTrim){
1399         pfp->vnp_top10->next = NULL;
1400         ValNodeFree(pfp->PopRowsList);
1401         pfp->PopRowsList = pfp->vnp_last;
1402         pfp->bSaved = FALSE;
1403       }
1404     }
1405     pfp->nPopRows++;
1406   }
1407 
1408   Ing_AddToDetailedPict(pfp->CurrentSeg, context, rowNum*(-20), &pfp->nSegs, leftmargin, rightmargin, scaleX);
1409   if (labels && pfp->showLabels){
1410     AddAttribute(pfp->CurrentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1411     if (over_the_edge)
1412       AddLabel (pfp->CurrentSeg, left -leftmargin, rowNum*(-20), str, SMALL_TEXT, 0,  UPPER_RIGHT, 0);
1413     else 
1414       AddLabel (pfp->CurrentSeg, left -leftmargin + (right-left)/2, rowNum*(-20), str, SMALL_TEXT, 0,  UPPER_CENTER, 0); 
1415   }
1416 
1417   pfp->nPrims++;
1418   return;
1419 }
1420 
1421 
1422 
1423 extern Uint4 Ing_PopDetailedPage(BioseqPtr bsp, SegmenT pictBottom, Int4 left, Int4 right, Uint1Ptr PNTR pClr, Int4 scaleX, Int4 start_row, Boolean Labels, Boolean isExons, IngTrackAlignsPtr tap)
1424 {
1425   IngPopFeat   pf;
1426   Uint2        entityID;
1427   SeqEntryPtr  sep;
1428   ValNodePtr   vnp=NULL;
1429   SeqAlignPtr  sap=NULL;
1430   SeqLocPtr    slp=NULL;
1431   Uint4        nPopRows=0;
1432   Int4         i;
1433   Int4         alignID;
1434   Int4         top = 0;
1435   Int4         len;
1436   IngSeqAnnotData  sad;
1437   SegmenT      CurrentSeg=NULL;
1438   Uint1Ptr     Clr=NULL;
1439   CharPtr PNTR names = NULL;
1440   Boolean      bUpdate = FALSE;
1441   IngContextPtr    context = NULL;
1442   enumPrimAddOrder oldOrder;
1443 
1444         memset(&pf,0,sizeof(pf));
1445         pf.pictMain=pictBottom;
1446         pf.pClr=pClr;
1447         pf.scaleX=scaleX;
1448    pf.nPrims=0;
1449    pf.nLevel1=0;
1450    pf.nLevel2=0;
1451    pf.nLevel3=0;
1452    pf.left=left;
1453    pf.right=right;
1454    pf.showLabels=Labels;
1455    pf.bSaved = FALSE;
1456    pf.bTrim = FALSE;
1457    pf.nPopRows=start_row;
1458    pf.PopRowsList = NULL;
1459    pf.group1 = NULL;
1460    pf.group1_last = NULL;
1461    pf.group2 = NULL;
1462    pf.group2_last = NULL;
1463    pf.group3 = NULL;
1464    pf.group3_last = NULL;
1465    pf.vnp_top10 = NULL;
1466    pf.vnp_last = NULL;
1467    slp=SeqLocIntNew(left, right, Seq_strand_plus, (SeqIdPtr)bsp->id);
1468         
1469    SeqMgrExploreFeatures (bsp, (Pointer) &pf,Ing_CollectFeatures2, slp, NULL, IngfeatDefFilter);
1470 
1471    if (pf.group1) {
1472      for (vnp = pf.group1; vnp != NULL; vnp = vnp->next){
1473        context = (IngContextPtr)vnp->data.ptrvalue;
1474        Ing_DrawDetailedPage(&pf, context);
1475        Ing_FreeContext(context);
1476      }
1477      ValNodeFree (pf.group1);
1478      pf.group1 = NULL;
1479      pf.group1_last = NULL;
1480    }
1481 
1482    if (pf.PopRowsList) ValNodeFree(pf.PopRowsList); 
1483    pf.PopRowsList = NULL;
1484    if (pf.group2){
1485      for (vnp = pf.group2; vnp != NULL; vnp = vnp->next){
1486        context = (IngContextPtr)vnp->data.ptrvalue;
1487        Ing_DrawDetailedPage(&pf, context);
1488        Ing_FreeContext(context);
1489      }
1490      ValNodeFree (pf.group2);
1491      pf.group2 = NULL;
1492      pf.group2_last = NULL;
1493    }
1494    if (pf.PopRowsList) ValNodeFree(pf.PopRowsList); 
1495    pf.PopRowsList = NULL;
1496    if (pf.group3){
1497      top = pf.nPopRows;
1498      pf.nPopRows++;
1499      oldOrder=ChangeAddPrimOrder(ADD_TO_HEAD);
1500      for (vnp = pf.group3; vnp != NULL; vnp = vnp->next){
1501        context = (IngContextPtr)vnp->data.ptrvalue;
1502        Ing_DrawDetailedPage(&pf, context);
1503        Ing_FreeContext(context);
1504      }
1505      len = right-left+1;
1506      ValNodeFree(pf.group3);
1507      pf.group3 = NULL;
1508      pf.group3_last = NULL;
1509 
1510      AddAttribute(pictBottom, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
1511      AddLabel(pictBottom, len/2 + (10*scaleX), top*(-20), context->name, SMALL_TEXT, 0, UPPER_CENTER, 0);
1512      AddAttribute(pictBottom, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1513      AddRectangle(pictBottom, (-10)*scaleX, top*(-20), len+(10*scaleX), pf.nPopRows*(-20), NO_ARROW, FALSE,0);
1514      ChangeAddPrimOrder(oldOrder);
1515    }
1516    if (pf.PopRowsList) ValNodeFree(pf.PopRowsList);
1517    pf.PopRowsList = NULL;
1518 
1519    CurrentSeg=CreateSegment(pictBottom,pf.nLevel1+1, 0);
1520    nPopRows=pf.nPopRows;
1521 
1522    /* get alignments */
1523    if (IngfeatDefFilter[0]){
1524      nPopRows+=2;
1525      entityID=ObjMgrGetEntityIDForPointer(bsp);
1526      sep = GetTopSeqEntryForEntityID(entityID); 
1527      if (tap && tap->update){
1528        sad.sindex= tap->showindex;
1529        sad.hindex= tap->hideindex;
1530        sad.aln_showlist = tap->showlist;
1531        sad.aln_namelist = tap->namelist;
1532        sad.aln_hidelist = tap->hidelist;
1533        sad.aln_hnamelist = tap->hnamelist;
1534        bUpdate = TRUE;
1535      }
1536      else if (!tap){
1537        sad.sindex = 0;
1538        sad.hindex= 0;
1539        sad.aln_showlist = NULL;
1540        sad.aln_namelist = NULL;
1541        sad.aln_hidelist = NULL;
1542        sad.aln_hnamelist = NULL;
1543        bUpdate = TRUE;
1544      }
1545      if (bUpdate){
1546        sad.tap = tap;
1547        SeqEntryExplore(sep,(Pointer)&sad, Ing_SearchAli);
1548        vnp = sad.aln_showlist;
1549        names = sad.aln_namelist;
1550        if (tap){
1551          tap->namelist = sad.aln_namelist;
1552          tap->showlist = sad.aln_showlist;
1553          tap->hidelist = sad.aln_hidelist;
1554          tap->hnamelist = sad.aln_hnamelist;
1555          tap->showindex = sad.sindex;
1556          tap->hideindex = sad.hindex;
1557          tap->update = FALSE;
1558        }
1559      }
1560      else {
1561        vnp = tap->showlist;
1562        names = tap->namelist;
1563      }
1564 
1565      if (!vnp) goto end;
1566      IngfeatDefTrack[0]=2;
1567      i=0;
1568      alignID=1;
1569      /* alignID is same as segID in Spidey Report */
1570      while(vnp){
1571        sap=(SeqAlignPtr)vnp->data.ptrvalue;
1572        AMAlignIndexFreeEitherIndex(sap);
1573        AlnMgr2IndexLite(sap);
1574        AlnMgr2SortAlnSetByNthRowPos(sap, 1);
1575        AssignIDsInEntity(entityID, OBJ_SEQALIGN, (Pointer)sap);
1576        Clr=Ing_GetAlignColor(names[i], pClr);
1577        nPopRows=Ing_AddAlignsToDetailedPage(pictBottom, &pf, sep, sap, nPopRows, left, right, Clr, scaleX, names[i], alignID, isExons);
1578        nPopRows+=2;
1579        i++;
1580        alignID++;
1581        vnp=vnp->next;
1582      }
1583    }
1584 
1585  end:
1586    SeqLocFree(slp);
1587    return (nPopRows);
1588    }
1589 
1590 
1591 
1592 
1593 
1594 /*******************************************************************************
1595 
1596   Function : Ing_GetValue()
1597  
1598   Purpose :  returns int value given TexT
1599 
1600 *******************************************************************************/
1601 
1602 extern Int4 Ing_GetValue (TexT t)
1603 {
1604   Char str[20];
1605   Int4 val;
1606 
1607   GetTitle (t,  str,  sizeof(str));
1608   if (StringHasNoText(str))
1609     {
1610       ErrPostEx (SEV_WARNING, 0, 0, "%s", "missing parameter(s)");
1611       return 0;
1612     }
1613 
1614   val=atoi(str);
1615 
1616   return val;
1617 }
1618 
1619 
1620 /*****************************************************************************
1621 
1622 Function: Ing_PutColor(), Ing_FreeColor(), Ing_BuildColorTable(), Ing_FreeColorTable(), Ing_GetMiscFeatColor(),
1623 
1624 Purpose: color functions
1625 
1626 *****************************************************************************/
1627 extern Uint1Ptr  Ing_PutColor(Uint1 r, Uint1 g, Uint1 b)
1628 {
1629   Uint1Ptr Clr;
1630 
1631   Clr = (Uint1Ptr)MemNew(sizeof(Uint1)*3);
1632   Clr[0]=r;
1633   Clr[1]=g;
1634   Clr[2]=b;
1635   return (Clr);
1636 }
1637 
1638 static Uint1Ptr Ing_FreeColor(Uint1Ptr Clr)
1639 {
1640   MemFree(Clr);
1641   return NULL;
1642 }
1643 
1644 
1645 static Uint1 Ing_GetMiscFeatColor(CharPtr str_4)
1646 {
1647 
1648   if (StringCmp(str_4, "red") == 0)
1649     return Ing_red;
1650   else if (StringCmp(str_4, "green") == 0)
1651     return Ing_green;
1652   else if (StringCmp(str_4, "blue")==0)
1653     return Ing_blue;
1654   else if (StringCmp(str_4, "cyan") == 0)
1655     return Ing_cyan;
1656   else if (StringCmp(str_4, "magenta") == 0)
1657     return Ing_magenta;
1658   else if (StringCmp(str_4, "yellow") == 0)
1659     return Ing_yellow;
1660   else if (StringCmp(str_4, "grey") == 0)
1661     return Ing_grey;
1662   else if (StringCmp(str_4, "purple") == 0)
1663     return Ing_purple;
1664   
1665   return Ing_black; /* default is black */
1666 }
1667 
1668 
1669 extern Uint1Ptr PNTR Ing_BuildColorTable(void)
1670 {
1671 Uint1Ptr PNTR pClr;
1672 
1673 
1674         pClr=(Uint1Ptr PNTR)MemNew(Ing_MAX*sizeof(Uint1Ptr));
1675         if (!pClr) return(NULL);
1676 
1677         pClr[FEATDEF_GENE]=Ing_PutColor(204,45,61); /*deep red*/
1678         
1679         pClr[FEATDEF_precursor_RNA]=Ing_PutColor(128,128,128);/*grey*/
1680         pClr[FEATDEF_misc_RNA]=Ing_PutColor(128,128,128);/*grey*/
1681         pClr[FEATDEF_preRNA]=Ing_PutColor(128, 128,128);/*grey*/
1682         pClr[FEATDEF_mRNA]=Ing_PutColor(0,127,0);/*green*/
1683         pClr[FEATDEF_tRNA]=Ing_PutColor(224,95,39);/* orange*/
1684         pClr[FEATDEF_rRNA]=Ing_PutColor(157,34, 28);/*sienna*/
1685         pClr[FEATDEF_snRNA]=Ing_PutColor(127,0,0);/* burnt sienna */
1686         pClr[FEATDEF_scRNA]=Ing_PutColor(119,45,0);/*brown*/
1687         pClr[FEATDEF_otherRNA]=Ing_PutColor(128,0,0);/*grey*/
1688         pClr[FEATDEF_prim_transcript]=Ing_PutColor(0,74, 0);/*green*/
1689         pClr[FEATDEF_polyA_signal]=Ing_PutColor(0,174, 0);/*green*/
1690         pClr[FEATDEF_polyA_site]=Ing_PutColor(0,200, 12);/*green*/
1691    pClr[FEATDEF_repeat_region]=Ing_PutColor(114,204,0)/* dk lime *//* (0,155,220) */;/*cyan*/
1692 
1693         pClr[FEATDEF_CDS]=Ing_PutColor(235, 150, 235);  /*pink*/
1694         pClr[FEATDEF_exon]=Ing_PutColor(192,50,150); /*fuschia */
1695         pClr[FEATDEF_intron]=Ing_PutColor(255,170,170);/* pale pink*/
1696 
1697         pClr[FEATDEF_PROT]=Ing_PutColor(0,0,128);               /*v dk blue*/
1698         pClr[FEATDEF_mat_peptide]=Ing_PutColor(64, 128, 192);/*pale blue*/
1699         pClr[FEATDEF_sig_peptide]=Ing_PutColor(204,0,61);/* dk red */
1700         pClr[FEATDEF_transit_peptide]=Ing_PutColor(224,224,0);/* lime */
1701         pClr[FEATDEF_preprotein]=Ing_PutColor(0, 19, 127);/*dk blue */
1702         pClr[FEATDEF_mat_peptide_aa]=Ing_PutColor(64, 128, 192);/*pale blue*/
1703         pClr[FEATDEF_sig_peptide_aa]=Ing_PutColor(63, 52, 90);/* indigo */
1704         pClr[FEATDEF_transit_peptide_aa]=Ing_PutColor(224,224,0);/* lime */
1705 
1706         pClr[FEATDEF_misc_feature]= Ing_PutColor(210, 154, 14 );/* curry */
1707 
1708 
1709         pClr[FEATDEF_SITE]=Ing_PutColor(255,0,0);               /*red*/
1710 
1711         pClr[FEATDEF_REGION]=Ing_PutColor(210,154,14);          /*orange*/
1712         pClr[FEATDEF_mutation]=Ing_PutColor(210,154,14);
1713         pClr[FEATDEF_variation]=Ing_PutColor(210,154,14);
1714 
1715         pClr[FEATDEF_PSEC_STR]=Ing_PutColor(104,201,220); /*cyan*/
1716    pClr[FEATDEF_STS]=Ing_PutColor(203, 52, 220); /*pale purple*/
1717  
1718         pClr[FEATDEF_HET]=Ing_PutColor(128,128,0);      /*yellow*/
1719 
1720         pClr[FEATDEF_BOND]=Ing_PutColor(255,92,255);    /*pink*/
1721    pClr[FEATDEF_unsure]=Ing_PutColor(104, 0, 40);/* dkred */
1722    pClr[FEATDEF_IMP]=Ing_PutColor(104, 0, 40);/* dkred */
1723    /* user defined */
1724         pClr[Ing_SPIDEY]=Ing_PutColor(0,200,112);/*green*/
1725    pClr[ALIGN_BLAST]=Ing_PutColor(155,145,0);
1726    pClr[ALIGN_FILE]=Ing_PutColor(145,155,255);
1727    pClr[ALIGN_ANNOT]=Ing_PutColor(255,92,55);
1728    pClr[ALIGN_BLAST2SEQ]=Ing_PutColor(25,92,255); 
1729    pClr[Ing_GENSCAN]=Ing_PutColor(204,45,61)/* (224,224,0) */;
1730    pClr[Ing_FEAT_TABLE]=Ing_PutColor(0,224,0);
1731    pClr[Ing_TBDL]=Ing_PutColor(0,224,155);
1732 
1733    /* extras */
1734    pClr[Ing_black]=Ing_PutColor(0,0,0);
1735    pClr[Ing_red]=Ing_PutColor(224, 0, 60);
1736    pClr[Ing_blue]=Ing_PutColor(0, 0, 255);
1737    pClr[Ing_cyan]=Ing_PutColor(0, 235, 245);
1738    pClr[Ing_yellow]=Ing_PutColor(235, 245, 0);
1739    pClr[Ing_grey]=Ing_PutColor(127, 127, 127);
1740    pClr[Ing_green] = Ing_PutColor(0,200,112);
1741    pClr[Ing_purple]=Ing_PutColor(163, 52, 190);
1742      
1743 
1744         return(pClr);
1745 }
1746 
1747 
1748 extern Uint1Ptr PNTR Ing_FreeColorTable(Uint1Ptr PNTR pClr)
1749 {
1750 
1751 
1752         if (!pClr) return(NULL);
1753 
1754         Ing_FreeColor(pClr[FEATDEF_GENE]);
1755         Ing_FreeColor(pClr[FEATDEF_precursor_RNA]);
1756    Ing_FreeColor(pClr[FEATDEF_misc_RNA]);
1757    Ing_FreeColor(pClr[FEATDEF_preRNA]);
1758    Ing_FreeColor(pClr[FEATDEF_mRNA]);
1759    Ing_FreeColor(pClr[FEATDEF_tRNA]);
1760    Ing_FreeColor(pClr[FEATDEF_rRNA]);
1761    Ing_FreeColor(pClr[FEATDEF_snRNA]);
1762    Ing_FreeColor(pClr[FEATDEF_scRNA]);
1763    Ing_FreeColor(pClr[FEATDEF_otherRNA]);
1764    Ing_FreeColor(pClr[FEATDEF_prim_transcript]);
1765    Ing_FreeColor(pClr[FEATDEF_polyA_signal]);
1766    Ing_FreeColor(pClr[FEATDEF_polyA_site]);
1767    Ing_FreeColor(pClr[FEATDEF_repeat_region]);
1768    Ing_FreeColor(pClr[FEATDEF_CDS]);
1769    Ing_FreeColor(pClr[FEATDEF_exon]);
1770    Ing_FreeColor(pClr[FEATDEF_intron]);
1771    Ing_FreeColor(pClr[FEATDEF_PROT]);
1772    Ing_FreeColor(pClr[FEATDEF_mat_peptide]);
1773    Ing_FreeColor(pClr[FEATDEF_sig_peptide]);
1774    Ing_FreeColor(pClr[FEATDEF_transit_peptide]);
1775    Ing_FreeColor(pClr[FEATDEF_preprotein]);
1776    Ing_FreeColor(pClr[FEATDEF_mat_peptide_aa]);
1777    Ing_FreeColor(pClr[FEATDEF_sig_peptide_aa]);
1778    Ing_FreeColor(pClr[FEATDEF_transit_peptide_aa]);
1779    Ing_FreeColor(pClr[FEATDEF_misc_feature]);
1780    Ing_FreeColor(pClr[FEATDEF_SITE]);
1781    Ing_FreeColor(pClr[FEATDEF_REGION]);
1782    Ing_FreeColor(pClr[FEATDEF_mutation]);
1783    Ing_FreeColor(pClr[FEATDEF_variation]);
1784    Ing_FreeColor(pClr[FEATDEF_PSEC_STR]);
1785    Ing_FreeColor(pClr[FEATDEF_STS]);
1786    Ing_FreeColor(pClr[FEATDEF_HET]);
1787    Ing_FreeColor(pClr[FEATDEF_BOND]);
1788    Ing_FreeColor(pClr[FEATDEF_unsure]);
1789    Ing_FreeColor(pClr[Ing_ORF]);
1790    Ing_FreeColor(pClr[Ing_SPIDEY]);
1791    Ing_FreeColor(pClr[ALIGN_BLAST]);
1792    Ing_FreeColor(pClr[ALIGN_FILE]);
1793    Ing_FreeColor(pClr[ALIGN_ANNOT]);
1794    Ing_FreeColor(pClr[ALIGN_BLAST2SEQ]);
1795    Ing_FreeColor(pClr[Ing_GENSCAN]);
1796    Ing_FreeColor(pClr[Ing_FEAT_TABLE]);
1797    Ing_FreeColor(pClr[Ing_TBDL]);
1798    Ing_FreeColor(pClr[Ing_black]);
1799    Ing_FreeColor(pClr[Ing_red]);
1800    Ing_FreeColor(pClr[Ing_blue]);
1801    Ing_FreeColor(pClr[Ing_cyan]);
1802    Ing_FreeColor(pClr[Ing_yellow]);
1803    Ing_FreeColor(pClr[Ing_grey]);
1804    Ing_FreeColor(pClr[Ing_purple]);
1805    MemFree(pClr);
1806    return NULL;
1807 }
1808 
1809 
1810 
1811 /*************************************************
1812 
1813   Function : Ing_ExploreSegments()
1814   
1815   Purpose : draw callback for SeqMgrExploreSegments()
1816 
1817 **************************************************/
1818 extern Boolean LIBCALLBACK Ing_ExploreSegments(SeqLocPtr slp, SeqMgrSegmentContextPtr context)
1819 {
1820   IngExploreSegsPtr  gpnp;
1821   Int4               left,top,right,bottom;
1822   Int4               left_ex, right_ex;
1823   Uint1              indigo[3], lime[3];
1824   Uint1              orange[3], black[3];
1825   Uint1              strand;
1826   GBBlockPtr         gbp = NULL;
1827   ValNodePtr         vnp = NULL;
1828   SeqIdPtr           sip = NULL;
1829   Boolean            isDraft = FALSE;
1830   Uint2              entityID = 0;
1831   Uint4              itemID = 0;
1832   OMUserDataPtr      omudp;
1833   Boolean            needs_label = TRUE;
1834 
1835    orange[0]= 210;
1836    orange[1]= 154;
1837    orange[2]= 14;
1838 
1839    black[0] = 0;
1840    black[1] = 0;
1841    black[2] = 0;
1842 
1843    indigo[0] = 163;
1844    indigo[1] = 52;
1845    indigo[2] = 90;
1846 
1847    lime[0] = 124;
1848    lime[1] = 224;
1849    lime[2] = 2;
1850 
1851         gpnp=(IngExploreSegsPtr)context->userdata;
1852    if (gpnp->idx)
1853      gpnp->idx++;
1854         left=context->from;
1855         right=context->to-left+context->cumOffset;
1856         left=context->cumOffset;
1857 
1858    if (!(gpnp->left==0 && gpnp->right==0)){
1859      left_ex=gpnp->left;
1860      right_ex=gpnp->right;
1861      if ((left<left_ex && right<left_ex)||(left>right_ex && right>right_ex)){
1862        return (TRUE);
1863      }
1864      else {
1865        left=MAX(left, left_ex)-left_ex;
1866        right=MIN(right, right_ex)-left_ex;
1867      }
1868    }
1869    
1870    slp = context->slp;
1871    strand=SeqLocStrand(slp);
1872 
1873      if (strand==Seq_strand_minus){
1874        AddAttribute(gpnp->seg, COLOR_ATT, orange, 0, 0, 0, 0);
1875      }
1876      else{
1877        AddAttribute(gpnp->seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1878      }
1879 
1880      
1881    top=gpnp->GrData->SegBoxHeight;
1882    if (gpnp->idx % 2)
1883      top-=gpnp->GrData->SegBoxHeight;
1884 
1885    bottom=top-gpnp->GrData->SegBoxHeight;
1886 
1887    sip = SeqLocId(slp);
1888 
1889    /* attach seqid to proc*/
1890    if ((sip != NULL) && gpnp->bRegister) {
1891      entityID = ObjMgrRegister(OBJ_SEQID, (Pointer)sip);
1892      itemID = GetItemIDGivenPointer (entityID, OBJ_SEQID, (Pointer) sip);
1893      omudp = ObjMgrAddUserData (entityID, gpnp->procID, OMPROC_VIEW, gpnp->userKey);
1894      omudp->messagefunc =  gpnp->messagefunc;
1895      omudp->userdata.ptrvalue = gpnp->data;
1896      omudp->procid = gpnp->procID;
1897    }
1898    
1899    if (gpnp->bLabels == FALSE || gpnp->bTop != FALSE || gpnp->scaleX > SEGMENT_SCALE){
1900      needs_label = FALSE;
1901    }
1902 
1903    Ing_AddGCRect(gpnp->seg, sip, entityID, itemID, OBJ_SEQID, gpnp->seqbuf, left, top, right, bottom, gpnp->scaleX, strand, needs_label, gpnp->bRegister, gpnp->idx, gpnp->bShowGC);
1904 
1905         return(TRUE);
1906 }
1907 
1908 
1909 
1910 static void Ing_GetLeftandRight(BioseqPtr bsp, SeqLocPtr slp, Int4Ptr left, Int4Ptr right)
1911 {
1912   if (slp){
1913     *left=GetOffsetInBioseq(slp, bsp, SEQLOC_LEFT_END);
1914     *right=GetOffsetInBioseq(slp, bsp, SEQLOC_RIGHT_END);
1915   }
1916   else{
1917     *left=0;
1918     *right=bsp->length-1;
1919   }
1920 }
1921 
1922 
1923 extern void Ing_AddGCRect(SegmenT seg, SeqIdPtr sip, Uint2 entityID, Uint4 itemID, Uint2 itemtype, Uint1Ptr seq, Int4 left, Int4 top, Int4 right, Int4 bottom, Int4 scaleX,  Uint1 strand, Boolean needs_label, Boolean clickable, Int4 idx, Boolean bShowGC)
1924 {
1925    Int4         a1, a2;
1926    Int4         c1, c2;
1927    Int4         g1, g2, t1, t2;
1928    Int4         gc_av, at_av, loopexit;
1929    Int4         i;
1930    Int4         j1, j2;
1931    Int4         len, length, start;
1932    Int4         n1, n2;
1933    FloatHi      comp2, comp_prev;
1934    FloatHi      comp_av;
1935    Char         szBuf[15]={""};
1936    Int4         pos, temp;
1937    Int4         window;
1938    Uint1Ptr     Clr;
1939    PrimitivE    prim;
1940    Boolean      is_loopexit =FALSE;
1941 
1942 
1943    a1 = a2 = c1 = c2 =  g1 = g2 = t1 = t2 = n1= n2 = 0;
1944    comp2 = comp_av = comp_prev = 0;
1945    window= scaleX*2 ; 
1946    start= left;
1947    length=right;
1948    if (start>length)
1949      {
1950        temp=start;
1951        start=length;
1952        length=temp;
1953      }
1954 
1955    if (needs_label){
1956      if (sip){
1957 /*        sip = GetSeqIdForGI(GetGIForSeqId(sip)); */
1958        sip = SeqIdFindBest(sip, SEQID_GENBANK);
1959        if (!sip)
1960          sip = SeqIdFindBest(sip, 0);
1961        SeqIdWrite(sip, szBuf,PRINTID_TEXTID_ACCESSION, 14);
1962      }
1963      else{
1964        sprintf(szBuf,"%d",idx);
1965      }
1966      if (idx % 2){
1967        AddLabel (seg, (idx==2 ? left : left+(right-left)/2), bottom, szBuf, SMALL_TEXT, 0, 
1968                  (idx==2 ? LOWER_RIGHT: LOWER_CENTER), 0);
1969      }
1970      else{
1971        AddLabel (seg, (idx==2 ? left : left+(right-left)/2), top, szBuf, SMALL_TEXT, 0, 
1972                  (idx==2 ? UPPER_RIGHT: UPPER_CENTER), 0);
1973      }
1974    }
1975 
1976    if (seq==NULL || !bShowGC){ 
1977      prim=AddRectangle (seg, left, top , right, bottom , NO_ARROW, TRUE, 0);
1978      /* clickable only on bottom panel */
1979      if (clickable) 
1980        SetPrimitiveIDs(prim, entityID, itemID, itemtype, itemtype);
1981    }
1982    else{
1983      pos = j1 = j2 = 0;
1984      at_av = 0;
1985      gc_av = 0;
1986      loopexit=length;
1987      
1988      for (i=start; i<loopexit; i++)
1989        {
1990          
1991          if (seq[i] == 1){
1992            a1++;
1993            a2++;
1994          }
1995          else if (seq[i] == 2){
1996            c1++;
1997            c2++;
1998          }
1999          else if (seq[i] == 4){
2000            g1++;
2001            g2++;
2002          }
2003          else if (seq[i] == 8){
2004            t1++;
2005            t2++;
2006          }
2007          else{
2008            n1++;
2009            n2++;
2010          }
2011          
2012          j1++;
2013          pos++;
2014      
2015          
2016          if (i==loopexit-1)
2017            is_loopexit=TRUE;
2018          if ((j1 == window) || is_loopexit)
2019            {
2020              len = MAX(1, j1 - n1);
2021              gc_av = ((255)*(g1+c1))/len; 
2022              at_av = ((255)*(a1+t1))/len;
2023              
2024              gc_av=gc_av>165?255:gc_av; /* gc > 65% */
2025              Clr=Ing_PutColor(0, gc_av, 0);
2026              if(Clr==NULL) Clr=Ing_PutColor(128, 128, 128);
2027              AddAttribute(seg, COLOR_ATT, (Clr?Clr:BLACK_COLOR), 0, 0, 0, 0);
2028              prim=AddRectangle (seg, left+(pos-j1), top , left+pos, bottom , 0, TRUE, 0);
2029              SetPrimitiveIDs(prim, entityID, itemID, itemtype, idx);
2030              MemFree(Clr); 
2031            a1 = c1 = t1 = g1 = n1 = 0;
2032            
2033            gc_av = at_av = 0;
2034            j1 = 0;
2035            }
2036        }
2037      
2038    }
2039 }
2040 
2041 extern void Ing_AddRuler(SegmenT seg, Int4 height, Int4 xstart,Int4 xstop, Int4 scaleX, Int4 scaleY, Boolean add_whitespace)
2042 {
2043   Int4         pos;
2044   Int4         xlen, x, y;
2045   Int4         scale_pos, i, j;
2046   Int4         bigtick, midtick, smalltick;
2047   Int4         line_Y;
2048   Int4         pos_2;
2049   Int4         pos_10;
2050   Int4         yBase;
2051   Char         scale_buf[35] = {""};    /*scale value*/
2052   Boolean      Decrement=FALSE;
2053   Int4         label;
2054   Int4         SeqLength;
2055 
2056   if (xstart>xstop)
2057     Decrement=TRUE;
2058 
2059   if (scaleX==0)
2060     scaleX=1;
2061   if (scaleY==0)
2062     scaleY=1;
2063 
2064   pos=100*scaleX;
2065   pos_2=pos/2;
2066   pos_10=pos/10;
2067   SeqLength=ABS(xstop-xstart)+1;
2068   bigtick=10*scaleY;
2069   midtick=7*scaleY;
2070   smalltick=5*scaleY;
2071   label=12*scaleY;
2072   line_Y=height+2*bigtick;
2073 
2074   xlen=ABS(xstop-xstart)+1;
2075   yBase = (-10)*FontHeight();
2076 
2077   AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2078   AddLine(seg, 0, line_Y, SeqLength, line_Y, FALSE,-1);
2079   if (add_whitespace){
2080     AddAttribute(seg, COLOR_ATT, WHITE_COLOR, 0,0,0,0);
2081     AddLine(seg, 0, yBase, SeqLength, yBase, FALSE,0);
2082   }
2083 
2084   sprintf(scale_buf, "len = %d", xlen);
2085   AddAttribute(seg, COLOR_ATT, RED_COLOR, 0,0,0,0);
2086   AddLabel(seg, xlen+4*scaleY, line_Y, scale_buf, SMALL_TEXT, 0, LOWER_LEFT, 0);
2087   
2088   AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2089   if (!Decrement)
2090     {
2091       for (scale_pos = 0, i=0; scale_pos <= xlen; scale_pos+=pos_10, i+=pos_10)
2092         {
2093           
2094           if (!(scale_pos % pos))
2095             {
2096               x = i;
2097               y = line_Y;
2098               AddLine(seg, x, y, x, y+bigtick, FALSE,-1);
2099               if (scale_pos != 0)
2100                 sprintf(scale_buf, "%d", (scale_pos+xstart));
2101               else 
2102                 sprintf(scale_buf, "1");
2103               AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
2104               AddLabel(seg, x, y+label, scale_buf, SMALL_TEXT, 0, UPPER_CENTER, 0);
2105               AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2106             }
2107           else if (!(scale_pos % (pos_2)))
2108             {
2109               x = i;
2110               y = line_Y;
2111               AddLine(seg, x, y, x, y+midtick, FALSE,-1);
2112               
2113             }
2114           else if (!(scale_pos % (pos_10)))
2115             {
2116               x = i;
2117               y = line_Y;
2118               AddLine(seg, x, y, x, y+smalltick, FALSE,-1);
2119             }
2120         }
2121     }
2122   else
2123     {
2124       for (scale_pos = 0, i=0, j=xstart; scale_pos <= xlen; scale_pos+=pos_10, i+=pos_10, j-=pos_10)
2125         {
2126           
2127           if (!(scale_pos % pos))
2128                 {
2129                   x = i;
2130                   y = line_Y;
2131                   AddLine(seg, x, y, x, y+bigtick, FALSE,-1);
2132                   sprintf(scale_buf, "%d", j);
2133                   AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
2134                   AddLabel(seg, x, y+label, scale_buf, SMALL_TEXT, 0, UPPER_CENTER, 0);
2135                   AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2136                 }
2137               else if (!(scale_pos % (pos_2)))
2138                 {
2139                   x = i;
2140                   y = line_Y;
2141                   AddLine(seg, x, y, x, y+midtick, FALSE,-1);
2142                   
2143                 }
2144               else if (!(scale_pos % (pos_10)))
2145                 {
2146                   x = i;
2147                   y = line_Y;
2148                   AddLine(seg, x, y, x, y+smalltick, FALSE,-1);
2149                 }
2150         }
2151     }
2152   
2153 }
2154 
2155 
2156 /*******************************************************************************
2157 
2158   Function : Ing_InitGrData()
2159   
2160   Purpose : initialize graphic objects
2161 
2162 *******************************************************************************/
2163 static FonT Ing_InitFont (void)
2164 {
2165   FonT f = NULL;
2166 
2167 #ifdef WIN_MAC
2168   f = ParseFont ("Monaco, 9");
2169 #endif
2170 
2171 #ifdef WIN_MSWIN
2172   f = ParseFont ("Courier, 7");
2173 #endif
2174 
2175 #ifdef WIN_MOTIF
2176   f = ParseFont ("fixed, 12");
2177 #endif
2178 
2179         return (f);
2180 
2181 }
2182 
2183 extern void Ing_InitGrData(IngGraphDataPtr gdp)
2184 {
2185   FonT f = NULL;
2186   
2187         /*font size*/
2188 
2189 /*   f = SetSmallFont(); */
2190   f = Ing_InitFont();
2191   if (f==NULL){
2192     gdp->cyChar=16;
2193     gdp->cxChar=8;
2194   }
2195   else{
2196     SelectFont(f);
2197     gdp->hFnt = f;
2198     gdp->cxChar=MaxCharWidth();
2199     gdp->cyChar=LineHeight();
2200   }
2201   
2202   /*values used to draw the rulers*/
2203   gdp->SegBoxHeight=gdp->cyChar/2;
2204   gdp->SegRulerTick=gdp->cyChar/2;
2205   gdp->SegRulerIn=3;
2206   
2207   /*colors*/
2208   gdp->pClr=Ing_BuildColorTable();      
2209 }
2210 
2211 /*******************************************************************************
2212 
2213   Function : Ing_PopulateSequinGraphic()
2214   
2215   Purpose : populate sequin viewer
2216 
2217 *******************************************************************************/
2218 extern SegmenT Ing_PopulateSequinGraphic(SegmenT seg, BioseqPtr bsp, Uint2 entityID, Uint4 itemID, Int4 scaleX)
2219 {
2220   IngExploreSegs     gpn;
2221   Int2               nSegments;
2222   PrimitivE          prim;
2223   IngGraphData       GrData;
2224   Int4               left, right;
2225 
2226   WatchCursor();
2227 
2228   Ing_InitGrData(&GrData);
2229   Ing_InitfeatDefFilter();
2230   gpn.seg=seg;
2231   gpn.viewer=NULL;
2232   gpn.idx=1;
2233   gpn.GrData=&GrData;
2234   Ing_GetLeftandRight(bsp, NULL, &left, &right);
2235   gpn.left=left;
2236   gpn.right=right;
2237   gpn.scaleX=scaleX;
2238   gpn.seqbuf=NULL;
2239   gpn.bTop = FALSE;
2240   gpn.bRegister = FALSE;
2241   gpn.bLabels = TRUE;
2242   nSegments=SeqMgrExploreSegments(bsp, (Pointer)&gpn, Ing_ExploreSegments);
2243 
2244   /*this bioseq doesn't have any segments*/
2245   if (nSegments==0){
2246     AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2247     prim=AddRectangle(seg,0, GrData.SegBoxHeight, bsp->length, 0,NO_ARROW,TRUE, 2);
2248     SetPrimitiveIDs(prim, entityID, itemID, OBJ_BIOSEQ, 2);
2249   }
2250 
2251   Ing_AddRuler(seg, 2*GrData.SegBoxHeight, left, right, scaleX, 1, FALSE);
2252   Ing_PopDetailedPage(bsp, seg, left, right, GrData.pClr, scaleX, 2, TRUE, FALSE, NULL);
2253   ArrowCursor();
2254   return (seg);
2255 }
2256 
2257 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.