NCBI C Toolkit Cross Reference

C/desktop/glbpic.c


  1 /*   panview.c
  2 *
  3 * File Name:  testseq.c
  4 *
  5 * Author: Jinghui Zhang
  6 *
  7 * Version Creation Date:   2/10/93
  8 *
  9 * File Description:
 10 *
 11 * Modifications:
 12 * --------------------------------------------------------------------------
 13 * Date     Name        Description of modification
 14 * -------  ----------  -----------------------------------------------------
 15 *11/6/93                used as a main() for testing the functions written
 16 *                       for the sequence displayer
 17 *                       SetFeatureProc can be reused universally
 18 *
 19 * ==========================================================================
 20 */
 21 
 22 #include <vibrant.h>
 23 #include <glbpic.h>
 24 #include <fstyle.h>
 25 #include <lsqfetch.h>
 26 #include <drawseq.h>
 27 
 28 #define MIN_WIDTH 20
 29 
 30 /***************************************************************************
 31 *
 32 *       functions related to freeing the GlobalDrawPtr
 33 *
 34 ****************************************************************************/
 35 static ValNodePtr GlobalDataFree(ValNodePtr gbp_list)
 36 {
 37         GlobalBspPtr gbp;
 38         ValNodePtr curr, next;
 39         AlignRegionPtr arp;
 40 
 41         while(gbp_list)
 42         {
 43                 gbp = gbp_list->data.ptrvalue;
 44                 next = gbp_list->next;
 45                 gbp_list->next = NULL;
 46                 
 47                 if(gbp->l_marks != NULL)
 48                         ValNodeFreeData(gbp->l_marks);
 49                 if(gbp->cyto_marks != NULL)
 50                         ValNodeFreeData(gbp->cyto_marks);
 51                 if(gbp->g_marks != NULL)
 52                         ValNodeFreeData(gbp->g_marks);
 53 
 54                 /*freeing the global display of repeat features and alignment*/
 55                 if(gbp->rrp_list)
 56                         ValNodeFreeData(gbp->rrp_list);
 57                 if(gbp->arp_list)
 58                 {
 59                         for(curr = gbp->arp_list; curr != NULL; curr = curr->next)
 60                         {
 61                                 arp = curr->data.ptrvalue;
 62                                 ValNodeFreeData(arp->intervals);
 63                         }
 64                         ValNodeFreeData(gbp->arp_list);
 65                 }
 66 
 67                 if(gbp->label)
 68                         MemFree(gbp->label);
 69                 ValNodeFreeData(gbp_list);
 70                 gbp_list = next;
 71         }
 72 
 73         return NULL;
 74 }
 75 
 76 static void separate_vnp_list(ValNodePtr PNTR head, ValNodePtr list)
 77 {
 78         ValNodePtr prev = NULL, curr;
 79 
 80         if(list == NULL)
 81                 return;
 82                         
 83         curr = *head;
 84         while(curr)
 85         {
 86                 if(curr == list)
 87                 {
 88                         if(prev == NULL)
 89                                 *head = NULL;
 90                         else
 91                                 prev->next = NULL;
 92                         return;
 93                 }
 94                 prev = curr;
 95                 curr = curr->next;
 96         }
 97 }
 98 
 99 /**************************************************************************
100 *
101 *       free_gkibak_draw(gdraw_p)
102 *       free all the data related to the global draw
103 *
104 ***************************************************************************/
105 GlobalDrawPtr free_global_draw(GlobalDrawPtr gdraw_p)
106 {
107         GlobalDataFree(gdraw_p->gbp_list);
108         
109         separate_vnp_list(&(gdraw_p->equiv_align_list), gdraw_p->ext_align);
110         ValNodeFree(gdraw_p->equiv_align_list);
111         
112         GeneDataFree(gdraw_p->g_data);
113         
114         if(gdraw_p->free_data)
115         {
116                 FreeEquivAlign(gdraw_p->ext_align);
117                 /* ValNodeFreeData(gdraw_p->g_list); */
118                 FreeMuskSep(gdraw_p->msp_list);
119         }
120         else
121                 ValNodeFree(gdraw_p->msp_list);
122                 
123 
124         /*there are selected slp_list*/
125         if(gdraw_p->slp_list)
126                 free_slp_list(gdraw_p->slp_list);
127         
128         MemFree(gdraw_p);
129         return NULL;
130 }
131 
132 /***************************************************************************
133 *
134 *       functions related to creating the GlobalDrawPtr
135 *
136 ****************************************************************************/           
137 /***************************************************************************
138 *
139 *       create the structure of GeneDataPtr from a list of gene symbols
140 *
141 ****************************************************************************/           
142 GeneDataPtr create_gene_data (ValNodePtr msp_list, ValNodePtr mark_list)
143 {
144         ValNodePtr curr;
145         MuskSepPtr msp;
146         GeneDataPtr gdp = NULL;
147         Int2 seglevels;
148         SeqEntryPtr sep;
149         BioseqPtr bsp;
150         SeqLoc sl;
151         SeqLocPtr slp;
152         
153         if(msp_list == NULL)
154                 return NULL;
155 
156                 
157         for(curr = msp_list; curr != NULL; curr = curr->next)
158         {
159                 msp = (MuskSepPtr)curr->data.ptrvalue;
160                 if(msp && msp->sep)
161                 {
162                         sep = msp->sep;
163                         bsp = find_big_bioseq(sep);
164                         if(bsp != NULL)
165                         {
166                                 seglevels = get_seglevels(bsp);
167                                 if(seglevels == 1)
168                                 {
169                                         sl.choice = SEQLOC_WHOLE;
170                                         sl.data.ptrvalue = bsp->id;
171                                         sl.next = NULL;
172                                         slp = &sl;
173                                 }
174                                 else
175                                         slp = NULL;
176 
177                                 load_gdata_marks(slp, mark_list, seglevels, msp->sep, &gdp);
178                         }
179                 }
180         }
181         
182         return gdp;
183 }
184 
185 
186 
187 /***************************************************************************
188 *
189 *       load the alignment data for landmark genes
190 *
191 ****************************************************************************/           
192 
193 static Boolean load_inconsistent_align(StdSegPtr ssp, Int4 min_inconsist_sp)
194 {
195         Int4 min_val, max_val;
196         SeqLocPtr slp;
197 
198         min_val = -1;
199         max_val = -1;
200         for(slp = ssp->loc; slp != NULL; slp = slp->next)
201         {
202                 if(min_val == -1)
203                         min_val = SeqLocStart(slp);
204                 else
205                         min_val = MIN(min_val, SeqLocStart(slp));
206                 if(max_val == -1)
207                         max_val = SeqLocStop(slp);
208                 else
209                         max_val = MAX(max_val, SeqLocStop(slp));
210         }
211 
212         return ((max_val - min_val + 1 ) > min_inconsist_sp);
213 }
214 
215 static Boolean load_std_seg(StdSegPtr ssp, SeqLocPtr location, ValNodePtr PNTR head, Uint1 type, Int4 min_inconsist_sp)
216 {
217         SeqLocPtr locs;
218         StdSegPtr t_ssp;
219 
220         for(locs = ssp->loc; locs != NULL; locs = locs->next)
221         {
222                 if(SeqLocCompare(locs, location) == SLC_A_EQ_B)
223                 {
224                         if(type == 2)   /*inconsistent markers*/
225                         {
226                                 if(min_inconsist_sp >0 && 
227                                         !load_inconsistent_align(ssp, min_inconsist_sp))
228                                         return TRUE;
229                         }
230                         if(*head == NULL)
231                                 ValNodeAddPointer(head, type, ssp);
232                         else
233                         {
234                                 t_ssp = (*head)->data.ptrvalue;
235                                 if(type == 4 || t_ssp->dim < ssp->dim)
236                                 {
237                                         (*head)->data.ptrvalue = ssp;
238                                         (*head)->choice = type; /*the type of markers. consistent/inconsistent*/
239                                 }
240                         }
241                         return TRUE;
242                 }
243         }
244         return FALSE;
245 }
246 
247 static Boolean check_std_align(SeqLocPtr location, SeqAlignPtr align, ValNodePtr PNTR head, Uint1 type, Int4 min_inconsist_sp)
248 {
249         StdSegPtr ssp;
250         if(align->type == 3)
251         {
252                 ssp = align->segs;
253                 while(ssp)
254                 {
255                         if(load_std_seg(ssp, location, head, type, min_inconsist_sp))
256                                 return TRUE;
257                         ssp = ssp->next;
258                 }
259         }
260         return FALSE;
261 }
262 
263 static void collect_equiv_align_for_landmark(GeneDataPtr gdp, ValNodePtr ealign_list, Int4 min_inconsist_sp)
264 {
265         SeqAnnotPtr annot;
266         SeqAlignPtr align;
267         GeneDataPtr curr;
268         Int2 type;
269         StdSegPtr ssp;
270         GeneDataPtr prev;
271 
272         if(gdp == NULL)
273                 return;
274         prev = gdp;
275         while(prev->next != NULL)
276                 prev = prev->next;
277 
278         while(ealign_list)
279         {
280           annot = (SeqAnnotPtr)(ealign_list->data.ptrvalue);
281           type  = GetEquivAlignType(annot);
282           if(type == -1)
283                 type = 1;
284           if(type  != 0 && type != 3) /*excluding alignment with type 3*/
285           {
286                 align = (SeqAlignPtr)(annot->data);
287                 if(type == 4)
288                 {
289                         while(align)
290                         {
291                                 ssp = align->segs;
292                                 while(ssp)
293                                 {
294                                         curr = MemNew(sizeof(GeneData));
295                                         ValNodeAddPointer(&(curr->align_seg), (Uint1)type, ssp);
296                                         prev->next = curr;
297                                         prev = curr;
298                                         ssp = ssp->next;
299                                 }
300                                 align = align->next;
301                         }
302                 }
303                 else
304                 {
305                         while(align)
306                         {
307                                 for(curr = gdp; curr!=NULL; curr = curr->next)
308                                 {
309                                         /* if(curr->landmark) */
310                                                 check_std_align(curr->location, align, &(curr->align_seg), (Uint1)type, min_inconsist_sp);
311                                 }
312                                                 
313                                 align = align->next;
314                         }
315                 }
316           }
317           ealign_list = ealign_list->next;
318         }
319 }
320 
321 
322 
323 
324 
325 static Boolean add_genedata_to_GlobalBsp(GlobalBspPtr g_bsp, GeneDataPtr gdp)
326 {
327         MapMarkPtr mmp;
328         
329         if(g_bsp == NULL || gdp == NULL)
330                 return FALSE;
331                 
332         while(gdp)
333         {
334                 if(BioseqMatch(g_bsp->bsp, SeqLocId(gdp->location)))
335                 {
336                         mmp = MemNew(sizeof(MapMark));
337                         /* StringCpy(mmp->label, gdp->symbol); */
338                         LabelCopy(mmp->label, gdp->symbol, 19);
339                         mmp->pos = (SeqLocStart(gdp->location) + SeqLocStop(gdp->location))/2;
340                         /*mmp->inward = IS_NUM_GENE(gdp->symbol);*/
341                         if(gdp->landmark)
342                                 ValNodeAddPointer(&(g_bsp->l_marks), 0, mmp);
343                         else
344                                 ValNodeAddPointer(&(g_bsp->g_marks), 0, mmp);
345                 }
346                 gdp = gdp->next;
347         }
348         return TRUE;
349 }
350 
351 
352 
353 static int LIBCALLBACK MapMarkCompProc (VoidPtr ptr1, VoidPtr ptr2)
354 {
355         MapMarkPtr mmp_1, mmp_2;
356         ValNodePtr vnp1, vnp2;
357 
358         if(ptr1!=NULL && ptr2 != NULL)
359         {
360                 vnp1 = *((ValNodePtr PNTR) ptr1);
361                 vnp2 = *((ValNodePtr PNTR) ptr2);
362                 if(vnp1 !=NULL && vnp2 != NULL)
363                 {
364                         mmp_1 = vnp1->data.ptrvalue;
365                         mmp_2 = vnp2->data.ptrvalue;
366                         if(mmp_1->pos > mmp_2->pos)
367                                 return 1;
368                         if(mmp_1->pos < mmp_2->pos)
369                                 return -1;
370                 }
371         }
372 
373         return 0;
374 }
375 
376 
377 static ValNodePtr sort_map_marker(ValNodePtr marks)
378 {
379         return SortValNode(marks, MapMarkCompProc);
380 }
381 
382 static ValNodePtr LoadCytoNode(BioseqPtr bsp, ValNodePtr PNTR head)
383 {
384         SeqFeatPtr sfp;
385         MapMarkPtr mmp;
386         UserObjectPtr uop;
387         Int4 pos;
388         SeqLocPtr slp;
389         CharPtr band_name;
390 
391         if(bsp->repr !=Seq_repr_map)
392                 return (*head);
393         sfp = bsp->seq_ext;
394         if(sfp->data.choice != 14)
395                 return (*head);
396         
397         while(sfp)
398         {
399                 slp = sfp->location;
400                 pos = (SeqLocStart(slp) + SeqLocStop(slp))/2;
401                 uop = sfp->data.value.ptrvalue;
402                 band_name = get_band_name(uop);
403                 if(band_name !=NULL)
404                 {
405                         mmp = MemNew(sizeof(MapMark));
406                         /* StringCpy(mmp->label, band_name); */
407                         LabelCopy(mmp->label, band_name, 19);
408                         mmp->pos = pos;
409                         mmp->inward = TRUE;
410                         ValNodeAddPointer(head, 1, mmp);
411                 }
412                 sfp = sfp->next;
413         }
414 
415         return (*head);
416 }
417 
418 /***************************************************************************
419 *
420 *       GlobalDataNew(): Create a ValNode that contains the information for 
421 *       bsp: the map Bioseq
422 *       map_type: the map type, such as GENETIC, PHYSICAL, etc
423 *       show_map_unit:  label the map unit in drawing
424 *       check_cyto:     checking if it is a cytogenetic map
425 *       head:           the pre-existing GlobalData.
426 *       gdp:    the GeneDataPtr which will map some into the individual 
427 *       The new GlobalData will be linked to the end of the head, and the 
428 *       return TRUE for a circular molecule. FALSE for a linear
429 *
430 ****************************************************************************/
431 static Boolean GlobalDataNew(BioseqPtr bsp, Uint1 map_type, Boolean show_map_unit, Boolean check_cyto, GeneDataPtr gdp, ValNodePtr PNTR head, Uint2 priority)
432 {
433         GlobalBspPtr g_bsp;
434         Uint1 val;
435 
436         if(bsp == NULL)
437                 return FALSE;
438 
439         g_bsp = MemNew(sizeof(GlobalBsp));
440         
441         g_bsp->hide = FALSE;    
442         g_bsp->bsp = bsp;
443         g_bsp->map_type = map_type;
444         g_bsp->show_map_unit = show_map_unit;
445         g_bsp->check_cyto = check_cyto;
446         g_bsp->l_marks = NULL;
447         g_bsp->g_marks = NULL;
448         g_bsp->cyto_marks = NULL;
449         g_bsp->priority = priority;
450         g_bsp->num_lod_score = GetLODScoreNumber (bsp);
451         if(priority == SEQINDEX_VAL)
452                 g_bsp->is_seqindex_map = TRUE;
453         if(check_cyto)
454                 LoadCytoNode(bsp, &(g_bsp->cyto_marks));
455                 
456         add_genedata_to_GlobalBsp(g_bsp, gdp);
457         g_bsp->l_marks = sort_map_marker(g_bsp->l_marks);
458 
459         if(bsp->topology == 2)
460                 val = CIRCLE_BSP;
461         else
462                 val = LINEAR_BSP;
463         ValNodeAddPointer(head, val, g_bsp);
464         return (val == CIRCLE_BSP);
465 }
466 
467         
468 static Int4 map_linear_xpos (Int4 pos, Int4 seq_len, Int4 left, Int4 right)
469 {
470         FloatHi temp;
471 
472         if(seq_len == 0)
473                 return -1;
474         temp = (FloatHi)pos * (FloatHi)(right - left)/(FloatHi)seq_len ;
475         
476         return (left + (Int4)temp);
477 }
478 
479 
480 static Int4 find_global_alignment_position (ValNodePtr PNTR list, Int4 left, Int4 right, Int4 width, Int4 offset)
481 {
482         BoolPtr line_data;
483         ValNodePtr curr;
484         ValNodePtr vnp, prev = NULL;
485         Int4 line = 0;
486         Int4 j;
487         Boolean found;
488         Int4 pix_space = 5;
489 
490         left -= offset;
491         right -= offset;
492 
493         found = FALSE;
494         curr = *list;
495         prev = NULL;
496         while(curr)
497         {
498                 line_data = curr->data.ptrvalue;
499                 if(line_data[left] == 0 && line_data[right] == 0)
500                 {
501                         found = TRUE;
502                         for(j = left; j<right; ++j)
503                         {
504                                 if(line_data[j] != FALSE)
505                                 {
506                                         found = FALSE;
507                                         break;
508                                 }
509                         }
510                 }
511                 if(!found)
512                 {
513                         prev = curr;
514                         ++line;
515                 }
516                 else
517                         break;
518                 curr = curr->next;
519         }
520 
521         if(!found)
522         {
523                 line_data = MemNew((size_t)width * sizeof(Boolean));
524                 vnp = ValNodeNew(NULL);
525                 vnp->data.ptrvalue = line_data;
526                 if(prev == NULL)
527                         *list = vnp;
528                 else
529                         prev->next = vnp;       
530         }
531 
532         left = MAX(0, left - pix_space);
533         right = MIN(width -1, right + pix_space);
534         MemSet(line_data+left, 1, (size_t)(right - left +1) * sizeof(Boolean));
535         return line;
536 }
537                         
538 
539                         
540 
541 static ValNodePtr layout_one_alignment_view(ValNodePtr arp_list, 
542         Int4 bsp_len, Int4 left, Int4 right, Boolean align_has_status)
543 {
544         Int4 num;
545         ValNodePtr curr;
546         Int4Ptr y_pos;
547         AlignRegionPtr arp;
548         Int4 t_left, t_right;
549         ValNodePtr line_data = NULL;
550 
551         if(arp_list == NULL)
552                 return NULL;
553 
554         line_data = NULL;
555         num = 0;
556         for(curr = arp_list; curr != NULL; curr = curr->next)
557         {
558                 arp = curr->data.ptrvalue;
559                 arp->g_left = map_linear_xpos (arp->gr.left, bsp_len, left, right);
560                 arp->g_right = map_linear_xpos (arp->gr.right, bsp_len, left, right);
561                 if(align_has_status)
562                         arp->line = find_global_alignment_position (&line_data, arp->g_left, arp->g_right, (right-left+1), left);
563                 else
564                         ++num;
565         }
566         ValNodeFreeData(line_data);
567         if(align_has_status)
568                 return (arp_list);
569 
570         /*for alignment that does not have status*/
571         y_pos = MemNew((size_t)(num*2) * sizeof(Int4));
572         for(curr = arp_list; curr != NULL; curr = curr->next)
573         {
574                 arp = curr->data.ptrvalue;
575                 t_left = arp->g_left;
576                 t_right = arp->g_right;
577                 arp->line = find_f_pos(t_left, t_right, y_pos, 1, (Int2)num);
578         }
579         MemFree(y_pos);
580         return (arp_list); 
581 }
582 
583 
584 static ValNodePtr extract_align_range(ValNodePtr PNTR arp_list, Uint1 displayOrder)
585 {
586         ValNodePtr curr, prev = NULL, list = NULL, p_list, next;
587         AlignRegionPtr arp;
588 
589         curr = *arp_list;
590         p_list = NULL;
591         prev = NULL;
592         while(curr)
593         {
594                 next = curr->next;
595                 arp = curr->data.ptrvalue;
596                 if(arp->displayOrder == displayOrder)
597                 {
598                         if(p_list == NULL)
599                                 list = curr;
600                         else
601                                 p_list->next = curr;
602                         p_list = curr;
603                         curr->next = NULL;
604                         if(prev == NULL)
605                                 *arp_list = next;
606                         else
607                                 prev->next = next;
608                 }
609                 else
610                         prev = curr;
611                 curr = next;
612         }
613 
614         return list;
615 }
616 
617 
618 
619 static Boolean layout_alignment_view(ValNodePtr arp_list, 
620         Int4 bsp_len, Int4 left, Int4 right, Boolean align_has_status)
621 {
622         ValNodePtr curr, prev, next;
623         AlignRegionPtr arp, n_arp;
624 
625         if(arp_list == NULL)
626                 return FALSE;
627         curr = arp_list;
628         while(curr)
629         {
630                 arp = curr->data.ptrvalue;
631                 next = curr->next;
632                 prev = curr;
633                 while(next)
634                 {
635                         n_arp = next->data.ptrvalue;
636                         if(n_arp->displayOrder == arp->displayOrder)
637                         {
638                                 prev = next;
639                                 next = next->next;
640                         }
641                         else
642                                 break;
643                 }
644 
645                 prev->next = NULL;
646                 layout_one_alignment_view(curr, bsp_len, 
647                         left, right, align_has_status);
648                 prev->next = next;
649                 curr = next;
650         }
651 
652         return TRUE;
653 }
654 
655 
656 
657 /****************************************************************
658 *
659 *       There are two cases that the alignments and repeats
660 *       need to be displayed together with the sequences in the 
661 *       global view
662 *       1) single sequence, show both repeats and alignments
663 *       2) multiple maps with FISH mapping data, show the alignments 
664 *          for the FISH mapping. No repeats
665 *
666 ****************************************************************/
667 static GlobalBspPtr find_bsp_for_repeat_align(ValNodePtr gbp_list, BoolPtr show_repeats)
668 {
669         GlobalBspPtr gbp;
670 
671         *show_repeats = FALSE;
672         if(gbp_list == NULL)
673                 return NULL;
674         if(gbp_list->next == NULL)
675         { /*single sequence*/
676                 gbp = gbp_list->data.ptrvalue;
677                 if(gbp->bsp == NULL)
678                         return NULL;
679                 *show_repeats = TRUE;
680                 return gbp;
681         }
682         else
683         {       /*check for the FISH alignment*/
684                 while(gbp_list != NULL)
685                 {
686                         gbp = gbp_list->data.ptrvalue;
687                         if(gbp->bsp)
688                         {
689                                 if (get_FISH_align (gbp->bsp))
690                                 {       
691                                         gbp->has_fish_align = TRUE;     
692                                         return gbp;
693                                 }
694                         }
695                         gbp_list = gbp_list->next;
696                 }
697 
698         }
699         return NULL;
700 }
701 
702 
703 /***************************************************************************
704 *
705 *       CreateGlobalDrawData(msp_list, ext_align, user_list, need_free)
706 *       Create the GlobalDrawPtr structure to draw the global view
707 *       msp_list: externally loaded Seq-entry and its file name (used for saving)
708 *       ext_align: the externally loaded sequence-alignment for equiv maps
709 *       user_list: a list of user-selected gene symbols
710 *       need_free: if TRUE, the free callback will free msp_list, ext_align and 
711 *       user_list.
712 *       if(for_picture), it will create the stuff for drawing the global view
713 *       otherwise, landmakrs, repeats, etc will not be created
714 *
715 ****************************************************************************/           
716 GlobalDrawPtr CreateGlobalDrawData(ValNodePtr msp_list, ValNodePtr ext_align, ValNodePtr user_list, Boolean need_free, Boolean for_picture, Uint1 equiv_align_option)
717 {
718         ValNodePtr bsp_list = NULL;
719         ValNodePtr e_align = NULL;
720         MuskSepPtr msp;
721         ValNodePtr vnp, new;
722         ValNodePtr landmarks = NULL;
723         Boolean show_map_unit;
724         Boolean check_cyto;
725         Uint1 bsptype = 0;
726         BioseqPtr bsp = NULL;
727         ValNodePtr global_bsp_data = NULL;
728         GeneDataPtr gdata_p = NULL;
729         Boolean is_circle = FALSE;
730         GlobalDrawPtr gdraw_p;
731         GlobalBspPtr gbp;
732         SeqLocPtr m_loc;
733         Int4 min_inconsist_sp;  /*mininal space between the inconsistent marks*/
734         Boolean show_repeats;
735 
736 
737         if(msp_list == NULL)
738                 return NULL;
739                 
740         /*get all the Bioseqs and equiv-aligns in Seq-entry*/
741         for(vnp = msp_list; vnp != NULL; vnp = vnp->next)
742         {
743                 msp = (MuskSepPtr)(vnp->data.ptrvalue);
744                 make_Bioseq_list (msp->sep, &bsp_list, &e_align);
745         }
746         if(bsp_list == NULL)
747                 return NULL;
748         if(ext_align != NULL)
749                 ValNodeLink(&e_align, ext_align);
750  
751                 
752         /*load the landmark genes*/
753         min_inconsist_sp = -1;
754         if(for_picture)
755         {
756                 for(vnp = msp_list; vnp != NULL; vnp = vnp->next)
757                 {
758                         msp = (MuskSepPtr)(vnp->data.ptrvalue);
759                         new = LoadLandMarkGene(msp->sep);
760                         ValNodeLink(&landmarks, new);
761                 }
762                 if(user_list != NULL)   /*link the user-supplied list of landmarks to the end*/
763                         ValNodeLink(&landmarks, user_list);
764                 if(landmarks != NULL)
765                 {
766                         gdata_p = create_gene_data (msp_list, landmarks);
767                         /*set the minimal space required for displaying the inconsistent marks*/
768                         if(bsp_list != NULL && equiv_align_option == EQUIV_ALIGN_DEFAULT)
769                         {
770                                 bsp = (BioseqPtr)(bsp_list->data.ptrvalue);
771                                 min_inconsist_sp = (bsp->length/5);
772                         }
773                         else
774                                 min_inconsist_sp = -1;
775 
776                         collect_equiv_align_for_landmark(gdata_p, e_align, min_inconsist_sp);
777                         if(user_list != NULL)
778                                 separate_vnp_list(&landmarks, user_list);
779                         if(landmarks != NULL)
780                                 ValNodeFreeData(landmarks);
781                 }
782         }
783 
784         
785         /*load data for individual Bioseq*/
786         for(vnp = bsp_list; vnp != NULL; vnp = vnp->next)
787         {
788                 bsp = (BioseqPtr)(vnp->data.ptrvalue);
789                 bsptype = get_Bioseq_type (bsp);
790                 switch(bsptype)
791                 {
792                         case RESTRICTION_MAP:
793                                 show_map_unit = FALSE;
794                                 check_cyto = FALSE;
795                                 break;
796                         case CYTO_MAP:
797                                 show_map_unit = FALSE;
798                                 check_cyto = TRUE;
799                                 break;
800                         default:
801                                 show_map_unit = TRUE;
802                                 check_cyto = FALSE;
803                                 break;
804                 }
805                 if(GlobalDataNew(bsp, bsptype, show_map_unit, check_cyto, gdata_p, &global_bsp_data, (Uint2)(vnp->choice)))
806                         is_circle = TRUE;
807         }
808         ValNodeFree(bsp_list);
809         
810         gdraw_p = MemNew(sizeof(GlobalDraw));
811         gdraw_p->gbp_list = global_bsp_data;
812         gdraw_p->ext_align = ext_align;
813         gdraw_p->equiv_align_list = e_align;
814         gdraw_p->msp_list = msp_list;
815         gdraw_p->free_data = need_free;
816         gdraw_p->g_data = gdata_p;
817         gdraw_p->g_list = user_list;
818         gdraw_p->is_circle = is_circle;
819         
820         /*collect the repeats and alignments for global display */
821         if(!is_circle && for_picture)
822         {
823                 gbp = find_bsp_for_repeat_align(gdraw_p->gbp_list, &show_repeats);
824                 if(gbp != NULL)
825                 {
826                         m_loc = SeqLocIntNew(0, gbp->bsp->length-1, Seq_strand_plus, SeqIdFindBest(gbp->bsp->id, 0));
827                         if(show_repeats)
828                                 collect_repeats_and_align (m_loc, &(gbp->rrp_list),  &(gbp->arp_list), 0, msp->sep, &(gbp->align_has_status));
829                         else
830                                 collect_repeats_and_align (m_loc, NULL,  &(gbp->arp_list), 0, msp->sep, &(gbp->align_has_status));
831                         SeqLocFree(m_loc);
832                 }
833         }
834 
835         return gdraw_p;
836 
837 }
838 
839 
840 /***************************************************************************
841 *
842 *       functions related to the layout of GlobalDrawPtr
843 *
844 *       LayoutGlobalDrawData(gdraw_p, pan_width, pan_height)
845 *       gdraw_p: the GlobalDrawPtr
846 *       pan_width: the width of the viewer
847 *       pan_height: the height of the viewer
848 *
849 ****************************************************************************/           
850 
851 static Int4 get_max_len(ValNodePtr bsp_data)
852 {
853         GlobalBspPtr gbp;
854         Int4 len = 0;
855 
856         while(bsp_data)
857         {
858                 gbp = (GlobalBspPtr)(bsp_data->data.ptrvalue);
859                 if(gbp && gbp->hide == FALSE)
860                         len = MAX(len, gbp->bsp->length);
861                 bsp_data = bsp_data->next;
862         }
863         return len;
864 }
865 
866 static Int2 get_curr_right(Int4 bsp_len, Int4 max_len, Int2 left, Int2 right)
867 {
868         FloatHi tmp_1;
869 
870         if(bsp_len == max_len)
871                 return right;
872         tmp_1 = (FloatHi)(bsp_len)/(FloatHi)(max_len);
873         tmp_1 *= (FloatHi)(right - left);
874         
875         return (left + (Int2)tmp_1);
876 }
877 
878 static Int4 get_max_label_len(ValNodePtr gbp_list)
879 {
880         Uint4 max_len = 0;
881         CharPtr seq_label = NULL;
882         GlobalBspPtr gbp;
883         FonT font;
884         Char label[21];
885         Uint1 format;
886         Int2 label_size;
887 
888         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
889         SelectFont(font);
890 
891         format = (Uint1)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_STYLE);
892         label_size = MIN(20, (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_LABEL, MSM_NUM));
893         while(gbp_list)
894         {
895                 gbp = gbp_list->data.ptrvalue;
896                 if(gbp && gbp->hide == FALSE )
897                 {
898                         if(gbp->label != NULL)
899                                 gbp->label = MemFree(gbp->label);
900                         if(MuskSeqIdWrite (gbp->bsp->id, label, label_size, format, TRUE, FALSE))
901                         {
902                                 gbp->label = StringSave(label);
903                                 if(StringLen(gbp->label) > max_len)
904                                 {
905                                         seq_label = gbp->label;
906                                         max_len = StringLen(gbp->label);
907                                 }
908                         }
909                 }
910                 gbp_list = gbp_list->next;
911         }
912         if(seq_label != NULL)
913                 return StringWidth(seq_label);
914         else
915                 return 0;
916 }
917 
918 
919 /* space for the Font plus the length of the tick mark. That is the 
920    immediate lines after the sequence */
921 static Int4 get_minimal_spacing(void)
922 {
923         FonT font;
924         Int4 font_height;
925 
926         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
927         SelectFont(font);
928         font_height= FontHeight();
929         
930         return (font_height + TICK_LEN);
931 }
932 
933         
934 /***********************************************************************
935 *
936 *       calculate the maximum vertical space needed for displaying the 
937 *       alignment globally (for powblast application)
938 *
939 ***********************************************************************/
940 static Int4 get_max_alignment_yspace(ValNodePtr arp_list, Boolean is_fish_align)
941 {
942         Int4 line_space = 6;
943         AlignRegionPtr arp;
944         Int4 max_space = 0, c_space;
945         Int4 pen_width;
946         Int4 displayOrder;
947         Int4 groupNum, group_space;
948         Boolean has_prev;
949         FonT font;
950         Int4 font_height;
951 
952         displayOrder = 0;
953         has_prev = FALSE;
954         c_space = 0;
955         groupNum = 0;
956         while(arp_list)
957         {
958                 arp = arp_list->data.ptrvalue;
959                 if(has_prev == FALSE || arp->displayOrder != displayOrder)
960                 {
961                         max_space += c_space;
962                         c_space = 0;
963                         displayOrder = arp->displayOrder;
964                         has_prev = TRUE;
965                         ++groupNum;
966                 }
967                 c_space = MAX(c_space, arp->line);
968                 arp_list = arp_list->next;
969         }
970         max_space += c_space;
971         if(is_fish_align)
972         {
973                 pen_width = 1;
974                 ++max_space;
975                 return ((max_space +1) * line_space*pen_width);
976         }
977         else
978         {
979                 if(groupNum > 1)
980                 {
981                         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
982                         SelectFont(font);
983                         font_height = FontHeight();
984                         group_space = font_height * groupNum + 2 * groupNum * line_space;
985                 }
986                 else
987                         group_space = 0;
988                 pen_width = MAX(1, GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_PENWIDTH));
989                 return ((max_space +1) * line_space*pen_width + group_space);
990         }
991 }
992 
993 static Int4 get_legend_space (void)
994 {
995         Int4 font_height;
996         FonT font;
997 
998         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
999         SelectFont(font);
1000         font_height = FontHeight();
1001         return (2*font_height + 2*GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT));
1002 }
1003 
1004 
1005 /*
1006 *       show_align_legend: if TRUE, draw a colored bar representing the 
1007 *       status of the alignemnts
1008 */
1009 static Boolean LayoutLinearDrawing(ValNodePtr g_bsp_list, Int2 pan_width, Int2 pan_height, Boolean show_align_legend)
1010 {
1011         Int2 space; 
1012         Int2 extra_space = 0;
1013         Int2 top, bottom, left, right, c_right;
1014         GlobalBspPtr gbp;
1015         ValNodePtr curr;
1016         Int2 num, lod_num;
1017         Int4 maxlen, max_label_len;
1018         Int2 box_height;
1019         Int2 maxHeight;
1020         Uint1 label_align;
1021         Int2 start_height =0;
1022         Int2 align_space;
1023         Int4 legend_space;
1024         Boolean align_has_status;
1025 
1026         
1027 
1028         /*calculate the number of sequences*/
1029         num = 0;
1030         lod_num = 0;
1031         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1032         {
1033                 gbp = curr->data.ptrvalue;
1034                 if(gbp->hide == FALSE)
1035                 {
1036                         ++num;
1037                         lod_num += (gbp->num_lod_score);
1038                 }
1039         }
1040         if(num == 0)
1041                 return FALSE;
1042         /*figure out the left and right margin*/
1043         label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_LABEL, MSM_STYLE);
1044         max_label_len = get_max_label_len(g_bsp_list);
1045         if(label_align == MSM_LABEL_RIGHT)
1046         {
1047                 left = max_label_len/2;
1048                 right = pan_width - (Int2)max_label_len;
1049         }
1050         else
1051         {
1052                 left = (Int2)max_label_len;
1053                 right = pan_width -max_label_len/2;
1054         }
1055         if(right - left < MIN_WIDTH)
1056                 return FALSE;
1057         maxlen = get_max_len(g_bsp_list);
1058 
1059         /*layout the alignemnts. Figure out the maximum space 
1060                 required for the alignments*/
1061         align_space = 0;
1062         align_has_status = FALSE;
1063         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1064         {
1065                 gbp = curr->data.ptrvalue;
1066                 if(gbp->hide == FALSE)
1067                 {
1068                         c_right = get_curr_right(gbp->bsp->length, maxlen, left, right);
1069                         gbp->rec.left = left;
1070                         gbp->rec.right = c_right;
1071                         if(gbp->arp_list != NULL)
1072                         {
1073                                 if(gbp->has_fish_align)
1074                                         align_has_status = FALSE;
1075                                 else
1076                                         align_has_status = gbp->align_has_status;
1077                                 layout_alignment_view(gbp->arp_list,
1078                                         gbp->bsp->length, left, c_right, align_has_status);
1079                                 align_space += (Int2)get_max_alignment_yspace(gbp->arp_list, gbp->has_fish_align);
1080                         }
1081                 }
1082         }
1083 
1084         if(show_align_legend && align_has_status)
1085         {
1086                 legend_space = get_legend_space ();
1087         }
1088         else
1089                 legend_space = 0;
1090 
1091         extra_space = (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1092         space = (Int2)get_minimal_spacing();
1093 
1094 
1095         box_height = (Int2)GetMuskCParam(MSM_SEQUENCE, MSM_SEGMENT, MSM_HEIGHT);
1096         if(box_height < 6)
1097                 box_height = 6;
1098         maxHeight = num*( box_height + space * 2) + (num -1) * extra_space + align_space + legend_space + lod_num * (box_height + extra_space * 2);
1099         if(legend_space > 0 || g_bsp_list->next == NULL || pan_height <= maxHeight)
1100                 start_height = 0;
1101         else
1102                 start_height = (pan_height - maxHeight)/(num + 1);
1103 
1104         top = (Int2)legend_space;
1105         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1106         {
1107                 gbp = curr->data.ptrvalue;
1108                 if(gbp->hide == FALSE)
1109                 {
1110                         top += (space + start_height);
1111                         if(gbp->arp_list != NULL)
1112                                 align_space = (Int2)get_max_alignment_yspace(gbp->arp_list, gbp->has_fish_align);
1113                         else
1114                                 align_space = 0;
1115 
1116                         bottom = top + box_height;
1117                         gbp->rec.top = top;
1118                         gbp->rec.bottom = bottom;
1119                         top = bottom + space + extra_space + align_space;
1120 
1121                         if(gbp->num_lod_score > 0)
1122                         {
1123                                 top += ((box_height + extra_space * 2)*gbp->num_lod_score);
1124                         }
1125                 }
1126         }
1127 
1128         return TRUE;
1129 }
1130 
1131 static Int2 get_circle_max_label(Int2 num)
1132 {
1133         Char label[21];
1134         Int2 i;
1135         FonT font;
1136 
1137         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1138         SelectFont(font);
1139         num = MIN(20, num);
1140         for(i = 0; i<num; ++i)
1141                 label[i] = 'X';
1142         label[i] = '\0';
1143         return (Int2)StringWidth(label);
1144 }
1145                 
1146                         
1147 static Boolean LayoutCircleDrawing(ValNodePtr g_bsp_list, Int2 pan_width, Int2 pan_height)
1148 {
1149         Int2 space, extra_space, max_space;
1150         Int2 radius;
1151         Int2 max_radius, min_radius;
1152         Int2 max_label_width;
1153         GlobalBspPtr gbp;
1154         Int2 num;
1155         ValNodePtr curr;
1156 
1157         num = 0;
1158         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1159         {
1160                 gbp = curr->data.ptrvalue;
1161                 if(gbp->hide == FALSE)
1162                         ++num;
1163         }
1164         if( num == 0)
1165                 return FALSE;
1166                 
1167         max_label_width = get_circle_max_label(10);
1168         if(pan_width - max_label_width > pan_height)
1169         {
1170                 pan_width = pan_height;
1171                 max_radius = pan_height/2;
1172         }
1173         else
1174         {
1175                 pan_width -= max_label_width;
1176                 max_radius = pan_width/2;
1177         }
1178         if(pan_width < MIN_WIDTH)
1179                 return FALSE;
1180         space = max_label_width/2 + TICK_LEN;
1181         extra_space = (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1182 
1183 
1184         max_space = 0;
1185         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1186         {
1187                 gbp = curr->data.ptrvalue;
1188                 if(gbp->hide == FALSE)
1189                 {
1190                         if(gbp->show_map_unit)
1191                                 max_space += space *2;
1192                         max_space += extra_space;
1193                 }
1194         }
1195         if(max_space != 0)      /*get rid of the last extra_space*/
1196                 max_space -= extra_space;
1197         min_radius = max_radius - max_space;
1198         radius = MAX(min_radius, 20);
1199 
1200         
1201         for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1202         {
1203                 gbp = curr->data.ptrvalue;
1204                 if(gbp->hide == FALSE)
1205                 {
1206                         if(gbp->show_map_unit)
1207                                 radius += space;
1208                         gbp->radius = radius;
1209                         if(gbp->show_map_unit)
1210                                 radius += space;
1211                         radius += extra_space;
1212                 }
1213         }
1214 
1215         return TRUE;
1216 }
1217 
1218                         
1219 Boolean LayoutGlobalDrawData(GlobalDrawPtr gdraw_p, Int2 pan_width, Int2 pan_height)
1220 {
1221 
1222         if(gdraw_p == NULL)
1223                 return FALSE;
1224         if(gdraw_p->is_circle)
1225         {
1226                 if(!LayoutCircleDrawing(gdraw_p->gbp_list, pan_width, pan_height))
1227                         return FALSE;
1228                 gdraw_p->center.x = pan_width/2;
1229                 gdraw_p->center.y = pan_height/2;
1230         }
1231         else
1232                 return LayoutLinearDrawing(gdraw_p->gbp_list, pan_width, pan_height, gdraw_p->draw_align_legend);
1233 
1234         return TRUE;
1235 }
1236 
1237 
1238         
1239 
1240 /************************************************************************
1241 *
1242 *   Draw_Global_Linear(bsp, show_map_unit, marks, check_cyto, p, rec)
1243 *       draw the global view of a linear molecule
1244 *       bsp: the map Bioseq
1245 *       show_map_unit:  label the map unit
1246 *       marks:  label any marks, such as genes associated with the map
1247 *       check_cyto:     check if it is a cytogenetic map
1248 *       p:      the PaneL for drawing
1249 *       rec:    the Rectangle that contains the map Bioseq
1250 *
1251 ************************************************************************/
1252 static void draw_linear_seqmark(SegmenT seg, Int4 length, Int4 left, Int4 top, Int4 right, Int4 bottom, NumberingPtr np)
1253 {
1254   Int4 scale, ruler;
1255   Int4 i;
1256   Int4 pos, x_pos;
1257 
1258   Char str[40];
1259   Int4 tick_len;
1260   Boolean use_kb;
1261   FonT font;
1262 
1263 
1264         scale = length/(right - left);
1265         if (length%(right - left) != 0)
1266                 ++scale;
1267         ruler = calculate_ruler(scale)/10;
1268         use_kb = (ruler >= 200);
1269         AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1270         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1271 
1272         i=0;
1273         pos = 0;
1274         while(pos < length)
1275         {                               /**mark the scales**/
1276                 tick_len = (i%5==0) ? TICK_LEN: TICK_LEN/2;
1277                 x_pos = map_linear_xpos(pos, length, left, right);
1278                 AddLine(seg, x_pos, bottom, x_pos, (bottom - tick_len), FALSE, 0);
1279                 if(i%5 ==0)     /*label the the interval*/
1280                 {
1281                         map_unit_label(pos, np, str, use_kb);
1282                         AddTextLabel(seg, x_pos, (bottom - tick_len), str, font, 0, LOWER_CENTER, 0);
1283                 }
1284 
1285                 ++i;
1286                 pos += ruler;
1287         }
1288 }
1289 
1290 
1291 static Boolean label_linear_mark(SegmenT seg, Int4 seqlen, ValNodePtr marks, Int4 left, Int4 top, Int4 right, Int4 bottom, Boolean ck_overlap)
1292 {
1293         FonT font;
1294         MapMarkPtr mmp;
1295         Int4 tick_len = TICK_LEN;
1296         Int4 x_pos, p_pos;
1297         Boolean drawit;
1298         Int4 pwidth = -1, width;
1299 
1300         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1301         SelectFont(font);
1302         p_pos = -1;
1303         while(marks)
1304         {
1305                 mmp = marks->data.ptrvalue;
1306                 x_pos = map_linear_xpos (mmp->pos, seqlen, left, right);
1307                 drawit = TRUE;
1308                 width = (Int2)StringWidth(mmp->label);
1309                 if(p_pos != -1 && ck_overlap && pwidth != -1)
1310                         drawit = ((x_pos - p_pos -2) > (pwidth + width)/2);
1311                 if(drawit)
1312                 {
1313                         if(mmp->inward)
1314                         {
1315                                 AddLine(seg, x_pos, bottom, x_pos, (bottom - TICK_LEN), FALSE, 0);
1316                                 AddTextLabel(seg, x_pos, (bottom - TICK_LEN), mmp->label, font, 0, LOWER_CENTER, 0);
1317                         }
1318                         else
1319                         {
1320                                 AddLine(seg, x_pos, top, x_pos, (top + TICK_LEN), FALSE, 0);
1321                                 AddTextLabel(seg, x_pos, (top + TICK_LEN), mmp->label, font, 0, UPPER_CENTER, 0);
1322                         }
1323                         pwidth = width;
1324                         p_pos = x_pos;
1325                 }
1326 
1327                 marks = marks->next;
1328         }
1329 
1330         return TRUE;
1331 }
1332 
1333 
1334 
1335 static void DrawInterval(Int4 start, Int4 stop, Int4 length, Int4 left, Int4 right, Int4 top, Int4 bottom, Boolean fill, SegmenT seg)
1336 {
1337         Int4 c_left, c_right;
1338         
1339         c_left = map_linear_xpos (start, length, left, right);
1340         c_right = map_linear_xpos (stop, length, left, right);
1341         AddRectangle(seg, c_left, top, c_right, bottom, NO_ARROW, fill, 0);
1342 }       
1343 
1344 
1345 
1346 static Boolean draw_human_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1347 {
1348         SeqFeatPtr sfp;
1349         UserObjectPtr uop;
1350         Int4 m_start, m_stop, length;
1351         Int2 i = 0;
1352         Uint1 band;
1353         Boolean draw_band;
1354         Uint1Ptr color;
1355         Uint1 shading;
1356 
1357 
1358         if(bsp->repr != Seq_repr_map)
1359                 return FALSE;
1360         sfp = bsp->seq_ext;
1361         if(sfp->data.choice != 14)
1362                 return FALSE;
1363 
1364         length = bsp->length;
1365         for(sfp = bsp->seq_ext; sfp !=NULL; sfp = sfp->next)
1366         {
1367                 ++i;
1368                 if(sfp->data.choice == 14)
1369                 {
1370                         uop = sfp->data.value.ptrvalue;
1371                         band  = get_band_type(uop);
1372                         draw_band = TRUE;
1373                         switch(band)
1374                         {
1375                                 case BAND_POINT:
1376                                         color = RED_COLOR;
1377                                         shading = SOLID_SHADING;
1378                                         break;
1379                                 case GIEMSA_POS:
1380                                         color = BLACK_COLOR;
1381                                         shading = SOLID_SHADING;
1382                                         break;
1383                                 case GIEMSA_NEG:
1384                                         color = WHITE_COLOR;
1385                                         shading = SOLID_SHADING;
1386                                         break;
1387                                 case ACRO_CENTRIC:
1388                                         color = BLACK_COLOR;
1389                                         shading = THICK_NWSE_SHADING;
1390                                         break;
1391                                 case VARIABLE_REG:
1392                                         color = BLACK_COLOR;
1393                                         shading = THIN_NESW_SHADING;
1394                                         break;
1395                                 default:
1396                                         draw_band = FALSE;
1397                                         break;
1398                         }
1399                         if(draw_band)
1400                         {
1401                                 m_start = SeqLocStart(sfp->location);
1402                                 m_stop = SeqLocStop(sfp->location);
1403                                 AddAttribute (seg, SHADING_ATT | COLOR_ATT, color, 0, shading, 0, NO_MODE);
1404                                 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1405                         }
1406                 }
1407         }
1408 
1409         return TRUE;
1410 }
1411 
1412 static Boolean draw_fly_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1413 {
1414         SeqFeatPtr sfp;
1415         UserObjectPtr uop;
1416         UserFieldPtr ufp;
1417         Int4 m_start, m_stop, length;
1418         Char subdiv[100];
1419         CharPtr curdiv;
1420         Boolean newseg;
1421         Uint1 band_type, prev_band;
1422         Int4 div =0;
1423         Boolean has_prev;
1424         Uint1Ptr color;
1425         Uint1 shading;
1426         Int2 num_subdiv = 0;
1427 
1428 
1429         if(bsp->repr != Seq_repr_map)
1430                 return FALSE;
1431         sfp = bsp->seq_ext;
1432         if(sfp->data.choice != 14)
1433                 return FALSE;
1434 
1435         length = bsp->length;
1436         subdiv[0] = '\0';
1437         has_prev = FALSE;
1438         div = 0;
1439         for(sfp = bsp->seq_ext; sfp !=NULL; sfp = sfp->next)
1440         {
1441                 uop = sfp->data.value.ptrvalue;
1442                 band_type = get_band_type(uop);
1443                 if(band_type ==TEL || band_type ==CEN)
1444                 {
1445                         if(has_prev)
1446                                 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1447                         AddAttribute (seg, SHADING_ATT | COLOR_ATT, RED_COLOR, NO_LINE_STYLE, SOLID_SHADING, 0, NO_MODE);
1448                         m_start = SeqLocStart(sfp->location);
1449                         m_stop = SeqLocStop(sfp->location);
1450                         DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1451                         has_prev = FALSE;
1452                         subdiv[0] = '\0';
1453                 }
1454                 else
1455                 {
1456                         if(has_prev)
1457                                 newseg = (prev_band != band_type);
1458                         else
1459                                 newseg = TRUE;
1460                                 
1461                         for(ufp = uop->data; ufp!=NULL; ufp = ufp->next)
1462                         {
1463                                 if(is_label_match(ufp->label, "Subdivision"))
1464                                 {
1465                                         curdiv = ufp->data.ptrvalue;
1466                                         if(StringCmp(subdiv, curdiv) !=0)
1467                                                 newseg = TRUE;
1468                                         if(newseg)
1469                                                 StringCpy(subdiv, curdiv);
1470                                 }
1471                                 if(is_label_match(ufp->label, "Division"))
1472                                         div = ufp->data.intvalue;
1473                         }
1474                         if(newseg)
1475                         {
1476                                 if(has_prev)
1477                                         DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1478                                 m_start = SeqLocStart(sfp->location);
1479                                 m_stop = SeqLocStop(sfp->location);
1480                                 has_prev = TRUE;
1481                                 prev_band = band_type;
1482                                 if(band_type == BND)
1483                                 {
1484                                         if(num_subdiv%2 == 0)   
1485                                                 shading = THIN_NESW_SHADING;
1486                                         else
1487                                                 shading = THIN_NWSE_SHADING;
1488                                         color = get_seg_color((Int2)div);
1489                                         ++num_subdiv;
1490                                 }
1491                                 else    /*for herterogen*/
1492                                 {
1493                                         shading = THIN_HORIZ_SHADING;
1494                                         color = BLACK_COLOR;
1495                                 }
1496                                 AddAttribute (seg, SHADING_ATT | COLOR_ATT, color, 0, shading, 0, NO_MODE);
1497                         }
1498                         else
1499                                 m_stop = SeqLocStop(sfp->location);
1500                 }
1501         }
1502         if(has_prev)
1503                 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1504         return TRUE;
1505 }
1506                 
1507 
1508 static Boolean draw_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1509 {
1510         SeqFeatPtr sfp;
1511         Uint1 cyto_type;
1512 
1513         if(bsp->repr == Seq_repr_map)
1514         {
1515                 sfp = (SeqFeatPtr)(bsp->seq_ext);
1516                 cyto_type = ck_cyto_type(sfp);
1517                 switch(cyto_type)
1518                 {
1519                         case HUMAN_CYTO:
1520                                 draw_human_cyto_map(bsp, left, top, right, bottom, seg);
1521                                 break;
1522                         case FLY_CYTO:
1523                                 draw_fly_cyto_map(bsp, left, top, right, bottom, seg);
1524                                 break;
1525                         default:
1526                                 return FALSE;
1527                 }
1528                 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
1529                 AddRectangle(seg, left, top, right, bottom, FALSE, FALSE, 0);
1530                 return TRUE;
1531         }
1532 
1533         return FALSE;
1534 }
1535 
1536 
1537 /**********************************************************
1538 *
1539 *       add_alignment_to_global: add the arp_list to the 
1540 *       global drawing
1541 *       bottom: the current y position of the picture
1542 *       add_to_bottom: TRUE, add the alignment to the bottom 
1543 *       of the picture, such as the regular sequence alignment
1544 *       FALSE: add to the top of the picture. ONLY for the FISH 
1545 *       mapping data
1546 *       return the next available y position
1547 *
1548 ***********************************************************/
1549 static Int4 add_alignment_to_global(SegmenT seg, ValNodePtr arp_list, 
1550         Int4 bottom, Boolean add_to_bottom, Int4 left, Int4 right, Int4 length)
1551 {
1552         Uint1 p_val;
1553         Int4 extra_space;
1554         Int4 line_count, maxline;
1555         Uint1 displayOrder;
1556         Int2 order;
1557         Boolean has_prev;       
1558         FonT font;
1559         Int4 font_height;
1560         Int4 g_top, g_bottom;
1561         CharPtr annotDB;
1562         Int4 m_start, m_stop, center;
1563         Int4 h_bottom;
1564         AlignRegionPtr arp;
1565         Int4 y_pos;
1566         Int4 pen_width;
1567         Int4 c_left, c_right;
1568         ValNodePtr intervals;
1569         GatherRangePtr grp;
1570         Uint1Ptr color;
1571 
1572         if(arp_list == NULL)
1573                 return bottom;
1574 
1575         extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1576         h_bottom = bottom;
1577         if(add_to_bottom)
1578                 bottom -= (extra_space + get_minimal_spacing());
1579         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1580         SelectFont(font);
1581         font_height = FontHeight();
1582         if(add_to_bottom)
1583                 pen_width = MAX(1, GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_PENWIDTH));
1584         else
1585                 pen_width = 1;
1586                 
1587         p_val = 1;
1588         color = BLACK_COLOR;
1589         displayOrder = 0;
1590         has_prev = FALSE;
1591         order = 0;
1592         maxline = 0;
1593         line_count = 0;
1594 
1595         AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
1596         while(arp_list)
1597         {
1598                 arp = arp_list->data.ptrvalue;
1599                 if(has_prev == FALSE || arp->displayOrder != displayOrder)
1600                 {       /*start of a new Seq-align cluster */
1601                         displayOrder = arp->displayOrder;
1602                         if(has_prev && add_to_bottom)
1603                         {       /*add the AlignNode box to the previous box*/
1604                                 g_bottom = bottom - (maxline + line_count)* (6+pen_width-1) - 8;
1605                                 color = get_seg_color(order);
1606                                 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, color, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
1607                                 AddRectangle (seg, left, g_top, right, g_bottom, FALSE, FALSE, 0);
1608                                 if(annotDB[0] != 0)
1609                                 {
1610                                         AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, WHITE_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
1611                                 
1612                                         c_left = (left + right)/2 - StringWidth(annotDB)/2 -10;
1613                                         c_right = c_left + StringWidth(annotDB) + 10;
1614                                         AddRectangle (seg, c_left, g_top+font_height/2, c_right, g_top-font_height/2, FALSE, TRUE, 0);
1615                                         
1616                                         
1617                                         AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, COPY_MODE); 
1618                                         AddTextLabel(seg, (left+right)/2, g_top, annotDB, font, 0, MIDDLE_CENTER, 0);
1619                                 }
1620                                 p_val = 0;
1621                                 bottom -= 16;
1622                                 line_count += maxline;
1623                         }
1624                         has_prev = TRUE;
1625                         annotDB = arp->annotDB;
1626                         ++order;
1627                         if(add_to_bottom)
1628                         {
1629                                 /* add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD); */
1630                                 g_top = bottom - line_count * (6 + pen_width-1);
1631                                 if(annotDB[0] != '\0')
1632                                 {
1633                                         g_top -= font_height/2;
1634                                         bottom -= font_height;
1635                                 }
1636                                 bottom -= 8;
1637                         }
1638                         else
1639                         {
1640                                 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, NO_MODE); 
1641                                 bottom -= 6;
1642                         }
1643                         maxline = 0;
1644 
1645                 }
1646                 maxline = MAX(maxline, arp->line);
1647 
1648 
1649                 switch(arp->status)
1650                 {
1651                         case 0:
1652                                 color = BLACK_COLOR;
1653                                 break;
1654                         case 1:
1655                                 color = BLUE_COLOR;
1656                                 break;
1657                         case 2:
1658                                 color = GREEN_COLOR;
1659                                 break;
1660                         case 3:
1661                                 color = MAGENTA_COLOR;
1662                                 break;
1663                         default:
1664                                 color = RED_COLOR;
1665                                 break;
1666                 }
1667                 m_start = arp->g_left; 
1668                 m_stop = arp->g_right;
1669 
1670                 /* m_start = arp->gr.left;
1671                 m_stop = arp->gr.right;
1672                 m_start = map_linear_xpos (m_start, length, left, right);
1673                 m_stop = map_linear_xpos (m_stop, length, left, right); */
1674                 y_pos = bottom - (arp->line + line_count) *(6 + pen_width-1);
1675                 if(add_to_bottom)
1676                 {       /*adding the info for the image maps*/
1677                         arp->g_left = m_start;
1678                         arp->g_right = m_stop;
1679                         arp->g_top = y_pos;
1680                         arp->g_bottom = arp->g_top - pen_width;
1681                 }
1682                 /*the sequence hits more than one region*/
1683                 intervals = arp->intervals;
1684                 if(add_to_bottom && (intervals != NULL && intervals->next != NULL))
1685                 {
1686                         if(pen_width == 1)
1687                         {
1688                                 AddAttribute(seg, COLOR_ATT|SHADING_ATT|MODE_ATT, YELLOW_COLOR, 0, DARK_SHADING, 0, COPY_MODE);
1689                                 AddLine(seg, m_start, y_pos, m_stop, y_pos, 0, FALSE);
1690                         }
1691                         else
1692                         {
1693                                 AddAttribute(seg, COLOR_ATT|SHADING_ATT|MODE_ATT, BLACK_COLOR, 0, THICK_NESW_SHADING, 0, COPY_MODE);
1694                                 AddRectangle (seg, m_start, y_pos, m_stop, y_pos-pen_width, FALSE, TRUE, 0);
1695                         }
1696                 }
1697 
1698                 AddAttribute(seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|MODE_ATT, color, SOLID_LINE , SOLID_SHADING, 0, COPY_MODE);
1699                 while(intervals)
1700                 {
1701                         grp = intervals->data.ptrvalue;
1702                         m_start = map_linear_xpos(grp->left, length, left, right);
1703                         m_stop = map_linear_xpos(grp->right, length, left, right);
1704                         if(pen_width == 1 || !add_to_bottom)
1705                                 AddLine(seg, m_start, y_pos, m_stop, y_pos, 0, FALSE);
1706                         else
1707                                 AddRectangle (seg, m_start, y_pos, m_stop, y_pos-pen_width, FALSE, TRUE, 0);
1708                         intervals = intervals->next;
1709                 }
1710 
1711 
1712                         
1713                 if(add_to_bottom == FALSE && y_pos != h_bottom)
1714                 {
1715                         /*add the lines to the FISH mapping */
1716                         center = (m_start + m_stop)/2;
1717                         AddLine(seg, center, y_pos, center, h_bottom, 0, FALSE);
1718                 }
1719                 /* if(p_val > 1)
1720                         AddLine(seg, m_start, y_pos+1, m_stop, y_pos+1, 0, FALSE); */
1721                 arp_list = arp_list->next;
1722         }
1723 
1724         if(order > 1 && add_to_bottom)
1725         {
1726                 g_bottom = bottom - extra_space - (maxline + line_count)* (6 + pen_width - 1) -8;
1727                 color = get_seg_color(order);
1728                 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, color, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
1729                 AddRectangle (seg, left, g_top, right, g_bottom, FALSE, FALSE, 0);
1730                 if(annotDB[0] != 0)
1731                 {
1732                         AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, WHITE_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
1733                 
1734                         c_left = (left + right)/2 - StringWidth(annotDB)/2 -10;
1735                         c_right = c_left + StringWidth(annotDB) + 10;
1736                         AddRectangle (seg, c_left, g_top+font_height/2, c_right, g_top-font_height/2, FALSE, TRUE, 0);
1737                                         
1738                         AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, COPY_MODE); 
1739                         AddTextLabel(seg, (left+right)/2, g_top, annotDB, font, 0, MIDDLE_CENTER, 0);
1740                 }
1741                 return g_bottom;
1742         }
1743         else
1744                 return (bottom - (maxline + line_count +1) * 6 );
1745 
1746 }
1747 
1748 static Boolean get_print_score(FloatHi min_score, FloatHi max_score, CharPtr label, Uint1 status)
1749 {
1750         FloatHi val;
1751 
1752         if(min_score == max_score)
1753                 return FALSE;
1754         if(status > 4)
1755                 return FALSE;
1756 
1757         switch(status)
1758         {
1759                 case 0:
1760                         val = min_score;
1761                         break;
1762                 case 4:
1763                         val = max_score;
1764                         break;
1765                 default:
1766                         val = min_score + (FloatHi)status * (max_score - min_score)/5.0;
1767                         break;
1768         }
1769 
1770         sprintf(label, "%.1lf", val);
1771         return TRUE;
1772 }
1773 
1774 
1775 
1776 static void DrawAlignScoreLegend(SegmenT seg, Int4 left, Int4 right, FloatHi min_score, FloatHi max_score)
1777 {
1778         FonT font;
1779         Int4 font_height, t_right;
1780         Int4 y_pos, box_width, box_height;
1781         Char buf[101], label[101];
1782         Int4 width;
1783         Int2 i;
1784         Int4 extra_space;
1785 
1786         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1787         SelectFont(font);
1788         font_height = FontHeight();
1789         /* box_height = (Int2)GetMuskCParam(MSM_SEQUENCE, MSM_SEGMENT, MSM_HEIGHT);
1790         box_height = MIN(font_height, box_height); */
1791         box_height = font_height;
1792         extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1793         t_right = right;
1794 
1795         StringCpy(buf, "Color Key for Alignment Scores");
1796         AddTextLabel(seg, (left+right)/2, 0, buf, font, 0, LOWER_CENTER, 0);
1797         y_pos = 0 - font_height - extra_space;
1798         width = 0;
1799         left += width/2;
1800         right -= width/2;
1801         box_width = (right - left)/5;
1802 
1803         /* StringCpy(buf, "lowest");
1804         AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1805         AddTextLabel(seg, left, y_pos-box_height/2, buf, font, 0, MIDDLE_LEFT, 0); */
1806 
1807         for(i = 0; i<5; ++i)
1808         {
1809                 right = left + box_width -1;
1810                 switch(i)
1811                 {
1812                         case 0:
1813                                 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1814                                 StringCpy(label, "<40");
1815                                 break;
1816                         case 1:
1817                                 AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
1818                                 StringCpy(label, "40-50");
1819                                 break;
1820                         case 2:
1821                                 StringCpy(label, "50-80");
1822                                 AddAttribute(seg, COLOR_ATT, GREEN_COLOR, 0, 0, 0, 0);
1823                                 break;
1824                         case 3:
1825                                 StringCpy(label, "80-200");
1826                                 AddAttribute(seg, COLOR_ATT, MAGENTA_COLOR, 0, 0, 0, 0);
1827                                 break;
1828                         default:
1829                                 StringCpy(label, ">=200");
1830                                 AddAttribute(seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
1831                                 break;
1832                 }
1833                 AddRectangle (seg, left, y_pos, right, y_pos-box_height, FALSE, TRUE, 0);
1834                 switch(i)
1835                 {
1836                         case 0:
1837                         case 1:
1838                                 AddAttribute(seg, COLOR_ATT, WHITE_COLOR, 0, 0, 0, 0);
1839                                 break;
1840                         default:
1841                                 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1842                                 break;
1843                 }
1844                 AddTextLabel(seg, (left+right)/2, y_pos-box_height/2-3, label, font, 0, MIDDLE_CENTER, 0);
1845                 left = right + 1;
1846         }
1847         AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1848         AddLine(seg, 0, y_pos-font_height-extra_space, t_right, y_pos-font_height-extra_space, 0, FALSE);
1849 }
1850                 
1851         
1852 static Boolean get_min_max_score (ValNodePtr arp_list, FloatHiPtr min_score, FloatHiPtr max_score)
1853 {
1854         AlignRegionPtr arp;
1855         ValNodePtr curr;
1856         Uint1 displayOrder;
1857         Boolean has_prev;
1858 
1859         *min_score = -1.0;
1860         *max_score = -1.0;
1861         has_prev = FALSE;
1862         displayOrder = 0;
1863 
1864         for(curr = arp_list; curr != NULL; curr = curr->next)
1865         {
1866                 arp = curr->data.ptrvalue;
1867                 if(!has_prev)
1868                 {
1869                         displayOrder = arp->displayOrder;
1870                         has_prev = TRUE;
1871                 }
1872                 else if(displayOrder != arp->displayOrder)      /*more than one group*/
1873                 {
1874                         *min_score = -1.0;
1875                         *max_score = -1.0;
1876                         return FALSE;
1877                 }
1878                         
1879                 if(*min_score == -1.0 || *min_score > arp->score)
1880                         *min_score = arp->score;
1881                 if(*max_score == -1.0 || *max_score < arp->score)
1882                         *max_score = arp->score;
1883         }
1884 
1885         return (*min_score < *max_score);
1886 }
1887 
1888 
1889 static Uint1Ptr MapLodScoreColor(SeqFeatPtr sfp)
1890 {
1891         Uint1 bit_val;
1892 
1893         bit_val =  GetLODScoreBitValue(sfp);
1894         switch(bit_val)
1895         {
1896                 case 1:
1897                         return BLUE_COLOR;
1898                 case 2:
1899                         return CYAN_COLOR;
1900                 case 3:
1901                         return GREEN_COLOR;
1902                 case 4:
1903                         return YELLOW_COLOR;
1904                 case 5:
1905                         return MAGENTA_COLOR;
1906                 case 6:
1907                         return RED_COLOR;
1908                 default:
1909                         return BLACK_COLOR;
1910         }
1911 }
1912         
1913         
1914 
1915 static Boolean  Draw_Global_Linear(GlobalBspPtr gbp, SegmenT seg, Boolean draw_align_legend)
1916 {
1917   BioseqPtr bsp;
1918   Boolean show_map_unit;
1919   Boolean check_cyto;
1920   FonT font;
1921   Uint1 label_align;
1922   Int4 middle;
1923   Uint1Ptr color;
1924 
1925   
1926   Int4 left, top, right, bottom;
1927   NumberingPtr np = NULL;
1928   Int4 length;
1929   Int2 i;
1930 
1931   SeqLocPtr slp;
1932   Int4 m_start, m_stop, pos;
1933   Boolean is_gap = FALSE;
1934   SeqIdPtr maybe_mapid; /*a possible id for map*/
1935   BioseqPtr t_bsp;
1936   
1937   /*for adding the repeat regions*/
1938   Uint1 p_val, shading;
1939   RepeatRegionPtr rrp;
1940   AlignRegionPtr arp;
1941   ValNodePtr curr;
1942   CharPtr label;
1943   Int4 seglen;
1944   Boolean skip;
1945 
1946   ValNodePtr rrp_list;
1947   FloatHi min_score, max_score;
1948   ValNodePtr delta_node;
1949   SeqLitPtr slitp;
1950 
1951   SeqAnnotPtr annot;
1952   SeqFeatPtr sfp;
1953   Int4 extra_space, space;
1954 
1955 
1956         if(gbp == NULL || gbp->bsp == NULL || gbp->hide)
1957                 return FALSE;
1958         bsp = gbp->bsp;
1959         show_map_unit = gbp->show_map_unit;
1960         check_cyto = gbp->check_cyto;
1961         left = (Int4)(gbp->rec.left);
1962         right = (Int4)(gbp->rec.right);
1963         top = -(Int4)(gbp->rec.top);
1964         bottom = -(Int4)(gbp->rec.bottom);
1965         length = bsp->length;
1966 
1967         /*draw the legend for alignment first*/
1968         if(gbp->has_fish_align == FALSE && gbp->arp_list != NULL)
1969         {
1970                 if(draw_align_legend)
1971                 {
1972                         for(curr = gbp->arp_list; curr != NULL; curr = curr->next)
1973                         {
1974                                 arp = curr->data.ptrvalue;
1975                                 if(arp->status > 0)
1976                                 {
1977                                         /*draw the legend for alignment score*/
1978                                         get_min_max_score (gbp->arp_list, &min_score, &max_score);
1979                                         DrawAlignScoreLegend(seg, left, right, min_score, max_score);
1980                                         break;
1981                                 }
1982                         }
1983                 }
1984         }
1985                 
1986 
1987         if(gbp->has_fish_align && gbp->arp_list != NULL)
1988         {
1989                 top = add_alignment_to_global(seg, gbp->arp_list, top, FALSE, left, right, length);
1990                 bottom = top - ABS(gbp->rec.top - gbp->rec.bottom);
1991         }
1992 
1993         /*add the sequence label*/
1994         label = gbp->label;
1995         if(label != NULL)
1996         {
1997                 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1998                 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1999                 label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_SLABEL, MSM_STYLE);
2000                 middle = (top + bottom)/2;
2001                 if(label_align == MSM_LABEL_RIGHT)
2002                         AddTextLabel(seg, right, middle, label, font, 0, MIDDLE_RIGHT, 0);
2003                 else
2004                         AddTextLabel(seg, left, middle, label, font, 0, MIDDLE_LEFT, 0);
2005         }
2006         
2007         if(bsp->repr != Seq_repr_seg && bsp->repr !=Seq_repr_delta)     
2008                 /*not a segmented entry or delta seq*/
2009         {
2010                 if(check_cyto)
2011                         draw_cyto_map(bsp, left, top, right, bottom, seg);
2012                 else
2013                 {
2014                         add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2015                         AddRectangle (seg, left, top, right, bottom, FALSE, TRUE, 0);
2016                         if(GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_TRUEFALSE))
2017                         {
2018                                 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2019                                 AddRectangle(seg, left, top, right, bottom, FALSE, FALSE, 0);
2020                         }
2021                 }
2022         }
2023         else if(bsp->repr == Seq_repr_seg)/*draw the segmented sequence*/
2024         {
2025                 slp = bsp->seq_ext;
2026                 maybe_mapid = figure_map_seqid(slp);
2027                 m_start = 0;
2028                 m_stop = -1;
2029                 i = 0;
2030                 while(slp)
2031                 {
2032                         ++i;
2033                         if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2034                         {
2035                                 seglen = SeqLocLen(slp);
2036                                 m_stop += seglen;
2037                                 if(seglen >10000 || (seglen * 10000 > bsp->length))
2038                                 {
2039                                         is_gap = is_map_segment(slp);
2040                                         if(!is_gap && maybe_mapid != NULL)
2041                                                 is_gap = (SeqIdMatch(maybe_mapid, SeqLocId(slp)));
2042                                         if(!is_gap)
2043                                         {
2044                                                 color = get_seg_color(i);
2045                                                 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2046                                                 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2047                                         }
2048                                 }
2049                                 m_start = m_stop + 1;
2050                         }
2051                         slp = slp->next;
2052                 }
2053                 skip = FALSE;
2054                 if(maybe_mapid != NULL)
2055                 {
2056                         t_bsp = BioseqFind(maybe_mapid);
2057                         if(t_bsp != NULL && t_bsp->repr == Seq_repr_map)
2058                                 skip = TRUE;
2059                 }
2060                 if(!skip)
2061                 {
2062                 /*add the gaps*/
2063                 m_start = 0;
2064                 m_stop = -1;
2065                 for(slp = bsp->seq_ext; slp != NULL; slp = slp->next)
2066                 {
2067                         pos = -1;
2068                         if(slp->choice == SEQLOC_NULL || slp->choice == SEQLOC_EMPTY)
2069                         {
2070                                 pos = map_linear_xpos (m_start, length, left, right);
2071                         }
2072                         else
2073                         {
2074                                 seglen = SeqLocLen(slp);
2075                                 m_stop += seglen;
2076                                 is_gap = is_map_segment(slp);
2077                                 
2078                                 if(is_gap && seglen * (right - left)/length < 4)
2079                                 {
2080                                         pos = map_linear_xpos((m_start+m_stop)/2, length, left, right);
2081                                 }
2082                                 m_start = m_stop + 1;
2083                         }
2084                         if(pos != -1)
2085                                 AddSymbol(seg, pos, (top+bottom)/2, DIAMOND_SYMBOL, FALSE, MIDDLE_CENTER, 0);
2086                 }
2087                 }
2088                                         
2089                 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2090                 AddRectangle (seg, left, top, right, bottom, FALSE, FALSE, 0);
2091         }
2092         else    /*it is a delta seq*/
2093         {
2094                 delta_node = bsp->seq_ext;
2095                 m_start = 0;
2096                 m_stop = -1;
2097                 i = 0;
2098                 while(delta_node)
2099                 {
2100                         is_gap = FALSE;
2101                         if(delta_node->choice == 1)
2102                         {
2103                                 slp = delta_node->data.ptrvalue;
2104                                 if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2105                                         seglen = SeqLocLen(slp);
2106                                 else
2107                                         is_gap = TRUE;
2108                         }
2109                         else    /*it is a literal seq*/
2110                         {
2111                                 slitp = delta_node->data.ptrvalue;
2112                                 if(slitp->length == 0 || slitp->seq_data == NULL)
2113                                 {
2114                                         is_gap = TRUE;
2115                                         if(slitp->length != 0)
2116                                         {
2117                                                 m_stop += slitp->length;
2118                                                 m_start = m_stop + 1;
2119                                         }
2120                                 }
2121                                 else
2122                                         seglen = slitp->length;
2123                         }
2124 
2125                         if(!is_gap)
2126                         {
2127                                 m_stop += seglen;
2128                                 color = get_seg_color(i);
2129                                 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2130                                 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2131                                 ++i;
2132                                 m_start = m_stop + 1;
2133                         }
2134                         delta_node = delta_node->next;
2135                 }
2136 
2137                 /*looking into small gaps*/
2138                 m_start = 0;
2139                 m_stop = -1;
2140                 delta_node = (ValNodePtr)(bsp->seq_ext);
2141                 while(delta_node)
2142                 {
2143                         is_gap = FALSE;
2144                         if(delta_node->choice == 1)
2145                         {
2146                                 slp = delta_node->data.ptrvalue;
2147                                 if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2148                                         seglen = SeqLocLen(slp);
2149                                 else
2150                                         is_gap = TRUE;
2151                         }
2152                         else    /*it is a literal seq*/
2153                         {
2154                                 slitp = delta_node->data.ptrvalue;
2155                                 if(slitp->length == 0 || slitp->seq_data == NULL)
2156                                 {
2157                                         is_gap = TRUE;
2158                                         if(slitp->length != 0)
2159                                         {
2160                                                 if(slitp->length * (right - left)/length >= 4)
2161                                                         is_gap = FALSE;
2162                                                 m_stop += slitp->length;
2163                                                 m_start = m_stop + 1;
2164                                         }
2165                                 }
2166                                 else
2167                                         seglen = slitp->length;
2168                         }
2169 
2170                         if(is_gap)
2171                         {
2172                                 pos = map_linear_xpos (m_start, length, left, right);
2173                                 AddSymbol(seg, pos, (top+bottom)/2, DIAMOND_SYMBOL, FALSE, MIDDLE_CENTER, 0);
2174                         }
2175                         else
2176                         {
2177                                 m_stop += seglen;
2178                                 m_start = m_stop + 1;
2179                         }
2180                         delta_node = delta_node->next;
2181                 }
2182         }
2183         
2184 
2185         AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE); 
2186         if(show_map_unit)
2187         {
2188                 np = getBioseqNumbering(bsp);
2189                 draw_linear_seqmark(seg, length, left, top, right, bottom, np);
2190         }
2191 
2192         if(gbp->cyto_marks != NULL)
2193         {
2194                 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2195                 label_linear_mark(seg, length, gbp->cyto_marks, left, top, right, bottom, TRUE);
2196         }
2197         if(gbp->l_marks != NULL)
2198         {
2199                 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2200                 label_linear_mark(seg, length, gbp->l_marks, left, top, right, bottom, TRUE);
2201         }
2202         if(gbp->g_marks != NULL)        /*user selected marks*/
2203         {
2204                 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
2205                 label_linear_mark(seg, length, gbp->g_marks, left, top, right, bottom, FALSE);
2206         }
2207         
2208         /*add the repeat unit*/
2209         if(gbp->rrp_list)
2210         {
2211                 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2212                 shading = LIGHT_SHADING;
2213                 AddAttribute(seg, SHADING_ATT, 0, 0, shading, 0, 0);
2214                 p_val = 0;
2215                 rrp_list = gbp->rrp_list;
2216                 while(rrp_list)
2217                 {
2218                         rrp = rrp_list->data.ptrvalue;
2219                         if(rrp_list->choice != p_val)
2220                         {
2221                                 p_val = rrp_list->choice;
2222                                 /*shading = p_val%4 + 6;
2223                                 shading = LIGHT_SHADING;
2224                                 AddAttribute(seg, SHADING_ATT, 0, 0, shading, 0, 0); */
2225                         }
2226                         m_start = rrp->gr.left;
2227                         m_stop = rrp->gr.right;
2228                         DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2229                         rrp_list = rrp_list->next;
2230                 }
2231         }
2232 
2233         /*add the global alignment as a result from powblast*/
2234         if(gbp->has_fish_align == FALSE && gbp->arp_list != NULL)
2235                 top = add_alignment_to_global(seg, gbp->arp_list, top, TRUE, left, right, length);
2236 
2237 
2238         /*add the LOD score plot*/
2239         if(gbp->num_lod_score > 0)
2240         {
2241                 extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
2242                 space = get_minimal_spacing();
2243                 bottom -= space;
2244                 for(annot = bsp->annot; annot != NULL; annot = annot->next)
2245                 {
2246                         if(is_lod_score_annot(annot))
2247                         {
2248                                 top = bottom -  2* extra_space;
2249                                 bottom = top - (gbp->rec.bottom - gbp->rec.top);
2250                                 for(sfp = annot->data; sfp != NULL; sfp = sfp->next)
2251                                 {
2252                                         color = MapLodScoreColor(sfp);
2253                                         AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2254                                         m_start = SeqLocStart(sfp->location);
2255                                         m_stop = SeqLocStop(sfp->location);
2256                                         DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2257                                 }
2258                                 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2259                                 AddRectangle (seg, left, top, right, bottom, FALSE, FALSE, 0);
2260 
2261                                 label = GetAnnotTitle(annot);
2262                                 if(label != NULL)
2263                                 {
2264                                         AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2265                                         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2266                                         label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_SLABEL, MSM_STYLE);
2267                                         middle = (top + bottom)/2;
2268                                         if(label_align == MSM_LABEL_RIGHT)
2269                                                 AddTextLabel(seg, right, middle, label, font, 0, MIDDLE_RIGHT, 0);
2270                                         else
2271                                                 AddTextLabel(seg, left, middle, label, font, 0, MIDDLE_LEFT, 0);
2272                                 }
2273                         }
2274                 }
2275         }
2276                                 
2277         return TRUE;
2278 }
2279 
2280 
2281 /*************************************************************************
2282 *
2283 *  Boolean  Draw_Global_Circle(bsp, show_map_unit, marks, p, radius, center)
2284 *       draw the global view of a circular genome. 
2285 *       bsp:    the map Bioseq
2286 *       show_map_unit:  display the map unit or not
2287 *       marks:  the marks, such as genes, to be displayed on the map
2288 *       p:      the drawing PaneL
2289 *       radius: the radius of the physical map
2290 *       center: the center of the circle
2291 *
2292 **************************************************************************/
2293 static FloatHi cal_angle_on_circle(Int4 pos, Int4 length)
2294 {
2295         return (FloatHi)pos/length * (FloatHi)2 * PI;
2296 }
2297 
2298 static Int4 cal_angle_with_mm_degree(Int4 pos, Int4 length)
2299 {
2300         FloatHi percent;
2301         Int4 angle;
2302         
2303         percent = (FloatHi)pos/(FloatHi)(length-1) * (FloatHi) 360000;
2304         angle = 90L * 1000L - (Int4)percent;
2305         if(angle < 0)
2306                 angle = 360000 + angle;
2307         return angle;
2308 }
2309 
2310 static void find_point_on_circle(FloatHi angle, PoinT center, Int2 radius, PointPtr c_pos)
2311 {
2312         FloatHi temp;
2313 
2314         temp = (FloatHi)radius * sin(angle); 
2315         c_pos->x  = center.x + (Int2)temp;
2316         temp = (FloatHi)radius * cos(angle); 
2317         c_pos->y = center.y - (Int2)temp;
2318 }
2319  
2320 
2321 static FloatHi  cal_mark_pos(Int4 pos, Int4 length, Int2 radius, PoinT center, Int2 tick_len, PointPtr p_start, PointPtr p_stop, Boolean inward)
2322 {
2323         FloatHi angle;
2324 
2325         angle = cal_angle_on_circle(pos, length);
2326         find_point_on_circle(angle, center, radius, p_start);
2327         if(inward)
2328                 radius -=tick_len;
2329         else
2330                 radius += tick_len;
2331 
2332         find_point_on_circle(angle, center, radius, p_stop);
2333         return angle;
2334 }
2335 
2336 
2337 static Uint1 get_circle_label_align(FloatHi angle, Boolean inward)
2338 {
2339         Uint1 align;
2340         
2341         if((angle >= 0 && angle <= (PI*0.25)) || (angle >= (PI*1.75) && angle <= (PI *2.0)))
2342                 align = inward ? LOWER_CENTER : UPPER_CENTER;
2343         if(angle > (PI * 0.25) && angle <= (PI * 0.75))
2344                 align = inward ? MIDDLE_LEFT : MIDDLE_RIGHT;
2345         if(angle > (PI * 0.75) && angle <= (PI * 1.25))
2346                 align = inward ? UPPER_CENTER : LOWER_CENTER;
2347         if(angle > (PI * 1.25) && angle <= (PI * 1.75))
2348                  align = inward ? MIDDLE_RIGHT: MIDDLE_LEFT;
2349         return align;
2350 }
2351 
2352 
2353 static void draw_circle_seqmark(SegmenT seg, Int4 length, PoinT center, Int2 radius, NumberingPtr np)
2354 {
2355   FloatHi temp;
2356   Int4 circle_len, scale, ruler;
2357   Boolean use_kb;
2358   Int4 i;
2359   Int4 pos;
2360 
2361   PoinT p_start, p_stop;
2362   FonT font;
2363   Char str[40];
2364   FloatHi angle;
2365   Int2 tick_len;
2366   
2367   Int4 left, top, right, bottom;
2368   Uint1 label_align;
2369 
2370 
2371         temp = 2.0 * PI * (FloatHi)radius;
2372         circle_len = (Int4)temp;
2373         scale = length/circle_len;
2374         if (length%circle_len!= 0)
2375                 ++scale;
2376         ruler = calculate_ruler(scale)/10;
2377         use_kb = (ruler >= 200);
2378         AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2379         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2380 
2381         i=0;
2382         pos = 0;
2383         while(pos < length)
2384         {                               /**mark the scales**/
2385                 tick_len = (i%5==0) ? TICK_LEN: TICK_LEN/2;
2386                 angle = cal_mark_pos(pos, length, radius, center, tick_len, &p_start, &p_stop, TRUE);
2387                 left = (Int4)(p_stop.x);
2388                 right = (Int4)(p_start.x);
2389                 top = - (Int4)(p_stop.y);
2390                 bottom = - (Int4)(p_start.y);
2391                 AddLine(seg, left, top, right, bottom, 0, FALSE);
2392                 if(i%5 ==0)     /*label the the interval*/
2393                 {
2394                         map_unit_label(pos, np, str, use_kb);
2395                         label_align = get_circle_label_align(angle, TRUE);
2396                         AddTextLabel(seg, left, top, str, font, 0, label_align, 0);
2397                 }
2398                 
2399                 ++i;
2400                 pos += ruler;
2401         }
2402 }
2403 
2404 static Boolean label_circle_mark(SegmenT seg, Int4 seqlen, ValNodePtr marks, PoinT center, Int2 radius, Boolean ck_overlap)
2405 {
2406         FonT font;
2407         MapMarkPtr mmp;
2408         Int2 tick_len = TICK_LEN;
2409         PoinT p_start, p_stop;
2410         FloatHi angle;
2411         Int4 p_top = -1, p_width = -1, p_left = -1;
2412         Int4 first_top, first_width, first_left;        /*first marker*/
2413         Int4 left, right, top, bottom;
2414         Int4 width;
2415         Int4 font_height;
2416         Boolean drawit;
2417         Uint1 label_align, p_align, first_align;
2418         Boolean has_prev = FALSE;
2419         Int4 t_width;
2420 
2421 
2422         font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2423         SelectFont(font);
2424         font_height = FontHeight();
2425         
2426         while(marks)
2427         {
2428                 mmp = marks->data.ptrvalue;
2429                 angle = cal_mark_pos(mmp->pos, seqlen, radius, center, tick_len, &p_start, &p_stop, mmp->inward);
2430                 width = StringWidth(mmp->label);
2431                 left = (Int4)(p_stop.x);
2432                 right = (Int4)(p_start.x);
2433                 top = - (Int4)(p_stop.y);
2434                 bottom = - (Int4)(p_start.y);
2435                 drawit = TRUE;
2436                 label_align = get_circle_label_align(angle, mmp->inward);
2437 
2438                 if(ck_overlap && has_prev)
2439                 {
2440                         t_width = (p_width + width)/2;
2441                         if(label_align != p_align)
2442                         {
2443                                 if(p_top != -1)
2444                                         if(ABS(p_top - top )< (font_height+3))
2445                                                 if(ABS(p_left - left) < (t_width +3))
2446                                                         drawit  = FALSE;
2447                         }
2448                         else
2449                         {
2450                                 switch(label_align)
2451                                 {
2452                                         case LOWER_CENTER : 
2453                                         case UPPER_CENTER :
2454                                                 if(ABS(p_left - left) < (t_width +3))
2455                                                         drawit = FALSE;
2456                                                 break;
2457                                         case MIDDLE_LEFT :
2458                                         case MIDDLE_RIGHT:
2459                                                 if(ABS(p_top - top )< (font_height+3))
2460                                                         drawit = FALSE;
2461                                                 break;
2462                                         default:
2463                                                 break;
2464                                 }
2465                         }
2466         
2467                         if(drawit && marks->next == NULL)
2468                         {
2469                                 t_width = (first_width + width)/2;
2470                                 if(label_align != first_align)
2471                                 {
2472                                         if(first_top != -1)
2473                                                 if(ABS(first_top - top )< (font_height+3))
2474                                                         if(ABS(first_left - left) < (t_width +3))
2475                                                                 drawit  = FALSE;
2476                                 }
2477                                 else
2478                                 {
2479                                         switch(label_align)
2480                                         {
2481                                                 case LOWER_CENTER : 
2482                                                 case UPPER_CENTER :
2483                                                         if(ABS(first_left - left) < (t_width +3))
2484                                                         drawit = FALSE;
2485                                                         break;
2486                                                 case MIDDLE_LEFT :
2487                                                 case MIDDLE_RIGHT:
2488                                                         if(ABS(first_top - top )< (font_height+3))
2489                                                                 drawit = FALSE;
2490                                                         break;
2491                                                 default:
2492                                                         break;
2493                                         }
2494                                 }
2495                         }
2496                 }
2497                 if(drawit)
2498                 {
2499                         p_top = top;
2500                         p_left = left;
2501                         p_width = width;
2502                         AddLine(seg, left, top, right, bottom, 0, FALSE);
2503                         AddTextLabel(seg, left, top, mmp->label, font, 0, label_align, 0);
2504                         p_align = label_align;
2505                         if(!has_prev)
2506                         {
2507                                 first_top = top;
2508                                 first_left = left;
2509                                 first_width = width;
2510                                 first_align = label_align;
2511                         }
2512                         has_prev = TRUE;
2513                 }
2514                 marks = marks->next;
2515         }
2516 
2517         return TRUE;
2518 }
2519 
2520                 
2521 
2522 static Boolean  Draw_Global_Circle(GlobalBspPtr gbp, SegmenT seg, PoinT center)
2523 {
2524   BioseqPtr bsp;
2525   Boolean show_map_unit;
2526   Int2 radius;
2527   
2528   NumberingPtr np = NULL;
2529   Int4 length;
2530   Int4 start_angle, stop_angle;
2531 
2532   SeqLocPtr slp;
2533   Int4 m_start, m_stop;
2534   Boolean is_gap;
2535   Int2 i;
2536   Uint1Ptr color;
2537   SeqIdPtr maybe_mapid; /*a possible id for map*/
2538   Int4 center_x, center_y;
2539  
2540 
2541 
2542         if(gbp == NULL || gbp->bsp == NULL || gbp->hide)
2543                 return FALSE;
2544         bsp = gbp->bsp;
2545         show_map_unit = gbp->show_map_unit;
2546         radius = gbp->radius;   
2547         length = bsp->length;
2548         add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2549 
2550         center_x = (Int4)(center.x);
2551         center_y = -(Int4)(center.y);
2552         if(bsp->repr != Seq_repr_seg)   /*not a segmented entry*/
2553                 AddOval(seg, center_x, center_y, radius, radius, FALSE, 0);
2554         else    /*draw the segmented sequence*/
2555         {
2556                 slp = bsp->seq_ext;
2557                 maybe_mapid = figure_map_seqid(slp);
2558                 m_start = 0;
2559                 m_stop = -1;
2560                 i = 0;
2561                 while(slp)
2562                 {
2563                         ++i;
2564                         m_stop += SeqLocLen(slp);
2565                         is_gap = is_map_segment(slp);
2566                         if(!is_gap && maybe_mapid != NULL)
2567                                 is_gap = (SeqIdMatch(maybe_mapid, SeqLocId(slp)));
2568                         if(!is_gap)
2569                         {
2570                                 start_angle = cal_angle_with_mm_degree(m_stop, length);
2571                                 stop_angle = cal_angle_with_mm_degree(m_start, length);
2572                                 if(start_angle == stop_angle)
2573                                 {
2574                                         if(slp == bsp->seq_ext)
2575                                         {
2576                                                 start_angle = 0;
2577                                                 stop_angle = 360000;
2578                                         }
2579                                 }
2580                                 color = get_seg_color(i);
2581                                 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2582                                 AddArc(seg, center_x, center_y, radius, radius, start_angle, stop_angle, FALSE, i);
2583                         }
2584                         m_start = m_stop +1;
2585                         slp = slp->next;
2586                 }
2587         }
2588 
2589         if(show_map_unit)
2590         {
2591                 np = getBioseqNumbering(bsp);
2592                 draw_circle_seqmark(seg, length, center, radius, np);
2593         }
2594 
2595         if(gbp->l_marks != NULL)
2596         {
2597                 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2598                 label_circle_mark(seg, length, gbp->l_marks, center, radius, TRUE);
2599         }
2600         if(gbp->g_marks != NULL)
2601         {
2602                 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
2603                 label_circle_mark(seg, length, gbp->g_marks, center, radius, FALSE);
2604         }
2605         
2606         return TRUE;
2607 }
2608 
2609 
2610 
2611 static void AddGeneEquivAlign(GeneDataPtr gdp, ValNodePtr gbsp_list, Boolean is_circle, PoinT center, SegmenT seg, Uint1 type)
2612 {
2613         StdSegPtr ssp;
2614         SeqLocPtr locs;
2615         SeqIdPtr sip;
2616         ValNodePtr curr;
2617         GlobalBspPtr gbsp;
2618         Int2 j;
2619         FloatHi angle;
2620         Int4 start, stop;
2621         Int4 length;
2622         Int4 left, right, top, bottom;
2623         PoinT pt;
2624         AlignPos ap;
2625         
2626         
2627         while(gdp)
2628         {
2629                 if(gdp->align_seg != NULL && gdp->align_seg->choice == type)
2630                 {
2631                         ssp = (StdSegPtr)(gdp->align_seg->data.ptrvalue);
2632                         j =0;
2633                         for(locs = ssp->loc; locs != NULL; locs = locs->next)
2634                         {
2635                                 sip = SeqLocId(locs);
2636                                 start = SeqLocStart(locs);
2637                                 stop = SeqLocStop(locs);
2638                                 for(curr = gbsp_list; curr != NULL; curr = curr->next)
2639                                 {
2640                                         gbsp = curr->data.ptrvalue;
2641                                         if(BioseqMatch(gbsp->bsp, sip))
2642                                         {
2643                                                 length = gbsp->bsp->length;
2644                                                 if(is_circle)
2645                                                 {
2646                                                         angle = cal_angle_on_circle(start, length);
2647                                                         find_point_on_circle(angle, center, gbsp->radius, &pt);
2648                                                         ap.left[j] = (Int4)(pt.x);
2649                                                         ap.top[j] = 0 - (Int4)(pt.y);
2650                                                         
2651                                                         angle = cal_angle_on_circle(stop, length);
2652                                                         find_point_on_circle(angle, center, gbsp->radius, &pt);
2653                                                         ap.right[j] = (Int4)(pt.x);
2654                                                         ap.bottom[j] = 0- (Int4)(pt.y);
2655                                                 }
2656                                                 else
2657                                                 {
2658                                                         left = (Int4)(gbsp->rec.left);
2659                                                         right = (Int4)(gbsp->rec.right);
2660                                                         top = - (Int4)(gbsp->rec.top);
2661                                                         bottom = - (Int4)(gbsp->rec.bottom);
2662                                                         ap.left[j] = map_linear_xpos (start, length, left, right);
2663                                                         ap.top[j] = top;
2664                                                         ap.right[j] = map_linear_xpos (stop, length, left, right);
2665                                                         ap.bottom[j] = bottom;
2666                                                 }
2667                                                 ++j;
2668                                                 break;
2669                                         }
2670                                 }
2671                         }
2672                         if(j >1)
2673                         {
2674                                 SortAlignPosition(&ap, j);
2675                                 draw_one_align(ap, j, 0, seg);
2676                         }
2677                 }
2678                 gdp = gdp->next;
2679         }
2680 }
2681 
2682 static GlobalBspPtr find_global_bsp(GlobalDrawPtr gdraw_p, SeqIdPtr sip)
2683 {
2684         ValNodePtr curr;
2685         GlobalBspPtr gbp;
2686         
2687         for(curr = gdraw_p->gbp_list; curr != NULL; curr = curr->next)
2688         {
2689                 gbp = curr->data.ptrvalue;
2690                 if(gbp && gbp->bsp != NULL)
2691                 {
2692                         if(BioseqMatch(gbp->bsp, sip))
2693                                 return gbp;
2694                 }
2695         }
2696         return NULL;
2697 }
2698         
2699         
2700 /*******************************************************************
2701 *
2702 *       map the selected regions into Points that will be used 
2703 *       for drawing the Polygons
2704 *
2705 *******************************************************************/
2706 static PntPtr map_selected_points(ValNodePtr slp_list, GlobalDrawPtr gdraw_p, Int2Ptr num)
2707 {
2708         PntPtr points;
2709         Int2 n;
2710         SeqLocPtr slp;
2711         PntPtr pnt;
2712         GlobalBspPtr gbp;
2713 
2714         if(gdraw_p->is_circle)
2715                 return NULL;
2716 
2717         n = get_vnp_num(slp_list);
2718         if(n == 0)
2719                 return NULL;
2720         ++n;    /*for the last point*/
2721         points = MemNew((size_t)2*n * sizeof(PntInfo));
2722 
2723         n = 0;
2724         while(slp_list)
2725         {
2726                 slp = slp_list->data.ptrvalue;
2727                 gbp = find_global_bsp(gdraw_p, SeqLocId(slp));
2728                 if(gbp != NULL)
2729                 {
2730                         if(gdraw_p->is_circle == FALSE)
2731                         {
2732                                 pnt = &(points[n]);
2733                                 pnt->x = map_linear_xpos(SeqLocStart(slp), 
2734                                         gbp->bsp->length, gbp->rec.left, gbp->rec.right);
2735                                 pnt->y = -(Int4)(gbp->rec.top);
2736                                 ++n;
2737 
2738                                 pnt = &(points[n]);
2739                                 pnt->x = map_linear_xpos(SeqLocStop(slp), 
2740                                         gbp->bsp->length, gbp->rec.left, gbp->rec.right);
2741                                 pnt->y = -(Int4)(gbp->rec.top);
2742                                 ++n;
2743 
2744                                 if(slp_list->next == NULL)      /*add the last one*/
2745                                 {
2746                                         /*the last point*/
2747                                         pnt = &(points[n]);
2748                                         pnt->x = points[n-2].x;
2749                                         pnt->y = -(Int4)(gbp->rec.bottom);
2750 
2751                                         ++n;
2752                                         pnt = &(points[n]);
2753                                         pnt->x = points[n-2].x;
2754                                         pnt->y = -(Int4)(gbp->rec.bottom);
2755                                         ++n;
2756                                 }
2757                         }
2758                 }
2759 
2760                 slp_list = slp_list->next;
2761         }
2762 
2763         *num = n;
2764         return points;
2765 }
2766                 
2767 /************************************************************************
2768 *
2769 *       Draw_Global(gdraw_p)
2770 *       return a picture created from GlobalDrawPtr
2771 *
2772 ************************************************************************/
2773 SegmenT Draw_Global(GlobalDrawPtr gdraw_p)
2774 {
2775         SegmenT pic;
2776         Boolean is_circle;
2777         GlobalBspPtr g_bsp;
2778         ValNodePtr gbp_list;
2779         PntPtr points;
2780         PntInfo pi[4];
2781         Int2 num, i;
2782         
2783         if(gdraw_p == NULL)
2784         {
2785                 Message(MSG_ERROR, "No Input Data");
2786                 return NULL;
2787         }
2788         
2789         pic = CreatePicture();
2790         
2791 
2792 
2793         /*draw the high-light of the selected region*/
2794         is_circle = gdraw_p->is_circle;
2795         if(gdraw_p->slp_list != NULL && !is_circle)
2796         {
2797                 points = map_selected_points(gdraw_p->slp_list, gdraw_p, &num);
2798                 if(points && num >= 4)
2799                 {
2800                         /* AddAttribute(pic, COLOR_ATT|STYLE_ATT|WIDTH_ATT, YELLOW_COLOR, DASHED_LINE, 0, 4, 0); */
2801                         AddAttribute(pic, COLOR_ATT, YELLOW_COLOR, 0, 0, 0, 0);
2802                         /* for(i = 0; i<(num/2-1); ++i)
2803                         {
2804                                 pnt_1 = &(points[2*i]);
2805                                 pnt_2 = &(points[2*(i+1)]);
2806                                 AddLine(pic, pnt_1->x, pnt_1->y, pnt_2->x, pnt_2->y, FALSE, 0);
2807                                 pnt_1 = &(points[2*i+1]);
2808                                 pnt_2 = &(points[2*(i+1)+1]);
2809                                 AddLine(pic, pnt_1->x, pnt_1->y, pnt_2->x, pnt_2->y, FALSE, 0);
2810                         } */
2811                         for(i = 0; i<(num/2-1); ++i)
2812                         {
2813                                 MemCopy(&(pi[0]), points+2*i, sizeof(PntInfo)); 
2814                                 MemCopy(&(pi[1]), points+2*i+1, sizeof(PntInfo)); 
2815                                 MemCopy(&(pi[2]), points+2*i+3, sizeof(PntInfo)); 
2816                                 MemCopy(&(pi[3]), points+2*i+2, sizeof(PntInfo)); 
2817                                 AddPolygon(pic, 4, (PntPtr)pi, TRUE, 0); 
2818                         }
2819                 }
2820                 if(points)
2821                         MemFree(points);
2822         }
2823 
2824         /*draw the green lines first*/
2825         add_attribute_pen(pic, MSM_ALIGNMENT, MSM_ALINE);
2826         AddAttribute(pic, STYLE_ATT, 0, SOLID_LINE, 0, 0, 0);
2827         AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 1);
2828         AddAttribute(pic, COLOR_ATT|STYLE_ATT, RED_COLOR, DOTTED_LINE, 0, 0, 0);
2829         AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 2);
2830  
2831         AddAttribute(pic, COLOR_ATT|STYLE_ATT, BLACK_COLOR, SOLID_LINE, 0, 0, 0);
2832         AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 4);
2833 
2834         for(gbp_list = gdraw_p->gbp_list; gbp_list != NULL; gbp_list = gbp_list->next)
2835         {
2836                 g_bsp = gbp_list->data.ptrvalue;
2837                 if(is_circle)
2838                         Draw_Global_Circle(g_bsp, pic, gdraw_p->center);
2839                 else
2840                         Draw_Global_Linear(g_bsp, pic, gdraw_p->draw_align_legend);
2841         }
2842         
2843         /* add_attribute_pen(pic, MSM_ALIGNMENT, MSM_ALINE);
2844         AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic);*/
2845 
2846         return pic;
2847 
2848 
2849 
2850 }
2851 
2852 
2853 SegmenT MuskGlobalPicture(ValNodePtr msp_list, ValNodePtr ext_align, Boolean need_free, Int2 panel_width, Int2 panel_height, ValNodePtr user_list, GlobalDrawPtr PNTR vwr_extra, Uint1 equiv_align_option, Boolean draw_align_legend)
2854 {
2855         GlobalDrawPtr gdraw_p;
2856         SegmenT pic;
2857         
2858         gdraw_p = CreateGlobalDrawData (msp_list, ext_align, user_list, need_free, TRUE, equiv_align_option);
2859         if(gdraw_p == NULL)
2860                 return NULL;
2861         
2862         gdraw_p->draw_align_legend = draw_align_legend;
2863         if(!LayoutGlobalDrawData (gdraw_p, panel_width, panel_height))
2864                 return NULL;
2865         pic = Draw_Global (gdraw_p);
2866         
2867         if(vwr_extra != NULL)
2868                 *vwr_extra = gdraw_p;
2869         else
2870         {
2871                 gdraw_p->free_data = FALSE;
2872                 free_global_draw (gdraw_p);
2873         }
2874         
2875         return pic;
2876 }
2877         
2878 
2879 SegmenT SequinGlobalPicture (SeqEntryPtr sep, Int2 panel_width, Int2 panel_height, ValNodePtr user_list, GlobalDrawPtr PNTR vwr_extra, Boolean draw_align_legend)
2880 {
2881         MuskSepPtr msp;
2882         ValNodePtr msp_list = NULL;
2883         SegmenT pic;
2884         
2885         msp = MemNew(sizeof(MuskSep));
2886         msp->sep = sep;
2887         msp->is_bin = TRUE;
2888         StringCpy(msp->file_name, "local.asn");
2889         ValNodeAddPointer(&msp_list, 0, (Pointer)msp);
2890         
2891         pic = MuskGlobalPicture(msp_list, NULL, FALSE, panel_width, panel_height, user_list, vwr_extra, 0, draw_align_legend);
2892         
2893         if(pic == NULL)
2894                 ValNodeFreeData(msp_list);
2895                 
2896         return pic;
2897 }
2898 
2899 
2900 SegmenT GlobalPictureUpdate(GlobalDrawPtr gdraw_p, ValNodePtr new_gene_list, Int2 panel_width, Int2 panel_height)
2901 {
2902         GeneDataPtr g_data;
2903         GlobalBspPtr gbp;
2904         ValNodePtr curr;
2905 
2906         if(gdraw_p == NULL)
2907                 return NULL;
2908 
2909         if(gdraw_p->gbp_list != NULL && gdraw_p->msp_list != NULL)
2910         {
2911                 curr = gdraw_p->gbp_list;
2912                 g_data = create_gene_data (gdraw_p->msp_list, new_gene_list);
2913 
2914                 if(g_data != NULL)
2915                 {
2916                         while(curr)
2917                         {
2918                                 gbp = (GlobalBspPtr)(curr->data.ptrvalue);
2919                                 gbp->g_marks = ValNodeFreeData(gbp->g_marks);
2920                                 add_genedata_to_GlobalBsp(gbp, g_data);
2921                                 curr = curr->next;
2922                         }
2923                         GeneDataFree(g_data);
2924                 } else {
2925                         while(curr)
2926                         {
2927                                 gbp = (GlobalBspPtr)(curr->data.ptrvalue);
2928                                 gbp->g_marks = ValNodeFreeData(gbp->g_marks);
2929                                 curr = curr->next;
2930                         }
2931                 }
2932                 gdraw_p->g_list = new_gene_list;
2933                 if(!LayoutGlobalDrawData (gdraw_p, panel_width, panel_height))
2934                         return NULL;
2935                 return Draw_Global (gdraw_p);
2936         }
2937         
2938         return NULL;
2939                 
2940 }
2941 
2942 
2943 /**********************************************************************
2944 *
2945 *
2946 *   Boolean find_map_pos(m_start, m_stop, start, stop, bsp_data, center)
2947 *       map the two points start, stop selected by rubber-band to an interval 
2948 *       on the sequence (m_start, m_stop). If selected region contains the 
2949 *       zero point across a circular molecule, *m_start > *m_stop
2950 *       bsp_data provide the mapping info. center is the center of a 
2951 *       circle. 
2952 *       return TRUE for success, FALSE for fail.
2953 *
2954 ************************************************************************/
2955 static Boolean check_linear_pnt(PoinT start, PoinT stop, RecT rec)
2956 {
2957         /*Int2 y_max, y_min;
2958 
2959         y_max = MAX(start.y, stop.y);
2960         y_min = MIN(start.y, stop.y);
2961         
2962         if(y_min > rec.top || y_max < rec.bottom)
2963                 return FALSE;
2964         else
2965                 return TRUE;*/
2966         if((start.x >= rec.right) && (stop.x >= rec.right))
2967                 return FALSE;
2968         if((start.x <= rec.left) && (stop.x <= rec.left))
2969                 return FALSE;
2970         return TRUE;
2971 }
2972 
2973 static Int4 convert_pnt_linear(PoinT pnt, RecT rec, Int4 seq_len)
2974 {
2975   Int2 x;
2976   Int2 start, stop, length;
2977   FloatHi temp;
2978 
2979         start = rec.left;
2980         stop = rec.right;
2981         length = stop - start;
2982         x = pnt.x;
2983         if(pnt.x < start)
2984                 x = start;
2985         if(pnt.x > stop)
2986                 x = stop;
2987         temp = (FloatHi)(x - start)/(FloatHi)length * (FloatHi)seq_len;
2988         return (Int4)temp;
2989 }
2990         
2991 
2992 static Int4 circle_pnt_to_map(FloatHi x_pos, FloatHi y_pos, Int2 radius, Int4 seq_len, PoinT center)
2993 {
2994 
2995    FloatHi angle;
2996    FloatHi temp;
2997    FloatHi center_x, center_y;
2998    Boolean x_minus, y_minus;
2999 
3000         center_x = (FloatHi)(center.x);
3001         center_y = (FloatHi)(center.y);
3002         x_minus = ((x_pos - center_x) < 0.0);
3003         y_minus = ((y_pos - center_y) < 0.0);
3004         temp = (x_pos - center_x)/(FloatHi)radius;
3005         if(x_minus)
3006                 temp = 0.0 - temp;
3007         angle = asin(temp);
3008         if(x_minus && y_minus)
3009                 angle = 2.0 * PI - angle;
3010         if(x_minus && !y_minus)
3011                 angle = PI + angle;
3012         if(!x_minus && !y_minus)
3013                 angle = PI - angle;
3014         temp = (FloatHi)seq_len * angle/((FloatHi)2.0 * PI);
3015         return (Int4)temp;
3016 }
3017 
3018 
3019 static Boolean get_cross_point(Int2 pos, Int2 border_1, Int2 border_2, Int4Ptr val_1, Int4Ptr val_2, Boolean is_x, Int2Ptr num_cross, Int2 radius, PoinT center, Int4 seq_len)
3020 {
3021     FloatHi val;
3022     FloatHi cross_offset;
3023     FloatHi x_pos, y_pos;
3024     FloatHi cross_val[2], cur_pos;
3025     FloatHi temp;
3026     Int2 i;
3027     Int4 map_pos;
3028    
3029 
3030         if(*num_cross == 2)
3031                 return TRUE;
3032 
3033         if(is_x)
3034         {
3035                 if(pos < (center.x - radius) || pos > (center.x + radius))
3036                         return FALSE;
3037                 val = (FloatHi)(pos - center.x);
3038         }
3039         else
3040         {
3041                 if(pos < (center.y - radius) || pos > (center.y + radius))
3042                         return FALSE;
3043                 val = (FloatHi)(pos - center.y);
3044         }
3045         temp = (FloatHi)radius * radius;
3046         cross_offset = sqrt(temp - val*val);
3047         if(cross_offset == 0.0)
3048                 Message(MSG_OK, "radius is %d, val is %lf", radius, val);
3049         if(is_x)
3050         {
3051                 cross_val[0] = (FloatHi)center.y + cross_offset;
3052                 cross_val[1] = (FloatHi)center.y - cross_offset;
3053         }
3054         else
3055         {
3056                 cross_val[0] = (FloatHi)center.x + cross_offset;
3057                 cross_val[1] = (FloatHi)center.x - cross_offset;
3058         }
3059 
3060 
3061 
3062          
3063         for(i = 0; i<2 && (*num_cross <2); ++i)
3064         {
3065                 cur_pos = cross_val[i];
3066                 if(cur_pos >= (FloatHi)border_1 && cur_pos <= (FloatHi)border_2)
3067                 {
3068                         x_pos = is_x ? (FloatHi)pos : cur_pos;
3069                         y_pos = is_x ? cur_pos : (FloatHi)pos;
3070                         map_pos = circle_pnt_to_map(x_pos, y_pos, radius, seq_len, center);
3071                         if(*num_cross == 0)
3072                         {
3073                                 *val_1 = map_pos;
3074                                 ++ (*num_cross);
3075                         }
3076                         else
3077                         {
3078                                 if(map_pos != *val_1)
3079                                 {
3080                                         *val_2 = map_pos;
3081                                         ++ (*num_cross);
3082                                 }
3083                         }
3084                 }
3085         }
3086                         
3087         return TRUE;
3088 
3089 }
3090 
3091 
3092 static Boolean get_point_on_circle(PoinT start, PoinT stop, Int4Ptr val_1, Int4Ptr val_2, Int2 radius, PoinT center, Int4 seq_len)
3093 {
3094    Int2 num =0;
3095    Int2 x_start, x_stop, y_start, y_stop;
3096 
3097         x_start = MIN(start.x, stop.x);
3098         x_stop = MAX(start.x, stop.x);
3099         y_start = MIN(start.y, stop.y);
3100         y_stop = MAX(start.y, stop.y);
3101 
3102         get_cross_point(x_start, y_start, y_stop, val_1, val_2, TRUE, &num, radius, center, seq_len);
3103         get_cross_point(x_stop, y_start, y_stop, val_1, val_2, TRUE, &num, radius, center, seq_len);
3104         get_cross_point(y_start, x_start, x_stop, val_1, val_2, FALSE, &num, radius, center, seq_len);
3105         get_cross_point(y_stop, x_start, x_stop, val_1, val_2, FALSE, &num, radius, center, seq_len);
3106 
3107         
3108         return (num ==2);       /*if two points on the circle are found or not*/
3109 
3110 }
3111 
3112 
3113 static  Int4 get_min_size(Int4 seq_len)
3114 {
3115         if(seq_len <= 350000)
3116                 return seq_len;
3117 
3118         return MAX(350000, seq_len/8);
3119 }
3120         
3121 static SeqLocPtr load_seq_loc(Int4 val_1, Int4 val_2, Int4 seq_len, Boolean has_zero, SeqIdPtr sip, BoolPtr show_msg, Boolean add_interval)
3122 {
3123   Int4 m_start, m_stop;
3124   Uint1 m_strand = Seq_strand_plus;
3125   SeqLocPtr slp = NULL, loc;
3126   Int4 min_len;
3127   Int4 temp;
3128   Int4 len;
3129 
3130         min_len = get_min_size(seq_len);
3131 
3132         
3133         if(has_zero)
3134         {
3135                 if(val_1 < val_2)
3136                 {
3137                         temp = val_2;
3138                         val_2 = val_1;
3139                         val_1 = temp;
3140                 }
3141                 if(add_interval)
3142                 {
3143                         val_1 -= seq_len/20;
3144                         val_2 += seq_len/20;
3145                 }
3146                 len = (seq_len - 1 - val_1 +1 + val_2 +1);
3147                 if(len > min_len)
3148                 {
3149                         if(*show_msg)
3150                                 Message(MSG_OK, "The selected region is too large. Reduced to %ld base pairs", min_len);
3151                         val_1 = seq_len - 1 - min_len/2;
3152                         val_2= min_len/2 -1;
3153                 }
3154                 m_start = val_1;
3155                 m_stop = seq_len -1;
3156                 loc = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3157                 m_start = 0;
3158                 m_stop = val_2;
3159                 loc->next = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3160                 slp = loc;
3161         }
3162         else
3163         {
3164                 m_start = MIN(val_1, val_2);
3165                 m_start = MAX(0, m_start);
3166 
3167                 m_stop = MAX(val_1, val_2);
3168                 m_stop = MIN(seq_len-1, m_stop);
3169                 len = m_stop - m_start + 1;
3170                 if(add_interval)
3171                 {
3172                         len += seq_len/10;
3173                         m_start = MAX(0, (m_start - seq_len/20));
3174                         m_stop = m_start + len -1;
3175                 }
3176 
3177                 /* if(len > min_len)
3178                 {
3179                         if(*show_msg)
3180                                 Message(MSG_OK, "The selected region is too large. Reduced to %ld base pairs", min_len);
3181                         center = (m_start + m_stop)/2;
3182                         m_start = center - min_len/2;
3183                         m_stop = m_start + min_len -1;
3184                 } */
3185                 slp = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3186         }
3187         *show_msg = FALSE;
3188         return slp;
3189 }
3190 
3191 static Boolean select_whole_circle(PoinT start, PoinT stop, PoinT center, Int2 r)
3192 {
3193         if(start.x < (center.x -r) && start.y < (center.y -r))
3194         {
3195                 if(stop.x > (center.x +r) && stop.y >(center.y+r))
3196                         return TRUE;
3197         }
3198 
3199         if(stop.x < (center.x -r) && stop.y < (center.y -r))
3200         {
3201                 if(start.x > (center.x +r) && start.y >(center.y+r))
3202                         return TRUE;
3203         }
3204 
3205         return FALSE;
3206 }
3207         
3208 
3209 static Boolean check_two_point(PoinT start, PoinT stop)
3210 {
3211         if(ABS(start.x - stop.x) < 3 && ABS(start.y - stop.y) < 3)
3212                 return TRUE;
3213         else
3214                 return FALSE;
3215 }
3216 
3217 static ValNodePtr find_circle_pos(PoinT start, PoinT stop, ValNodePtr gbp_list, PoinT center)
3218 {
3219 
3220   RecT or;
3221   PoinT zero_pnt;
3222   Int4 val_1, val_2;
3223   FloatHi percent_1, percent_2;
3224   FloatHi temp;
3225 
3226   ValNodePtr curr;
3227   GlobalBspPtr gbp;
3228   BioseqPtr bsp;
3229   Int4 seq_len;
3230   Boolean is_found = FALSE;
3231   Boolean has_zero = FALSE;
3232   SeqLocPtr slp;
3233   ValNodePtr slp_list = NULL;
3234   Boolean show_msg = TRUE;
3235   Boolean add_interval;
3236 
3237 
3238         add_interval = check_two_point(start, stop);
3239         for(curr = gbp_list; curr !=NULL && !is_found; curr = curr->next)
3240         {
3241                 gbp = curr->data.ptrvalue;
3242                 bsp = gbp->bsp;
3243                 seq_len = bsp->length;
3244                 if(select_whole_circle(start, stop, center, gbp->radius))
3245                 {
3246                         is_found = TRUE;
3247                         val_1 =0;
3248                         val_2 = seq_len -1;
3249                 }
3250                 else
3251                 {
3252                         zero_pnt.x = center.x;
3253                         zero_pnt.y = center.y - gbp->radius;
3254                         LoadRect (&or, start.x, start.y, stop.x, stop.y);
3255                         has_zero = PtInRect(zero_pnt, &or);
3256                         is_found = get_point_on_circle(start, stop, &val_1, &val_2, gbp->radius, center, seq_len);
3257                 }
3258         }
3259 
3260 
3261         if(is_found)
3262         {
3263                 percent_1 = (FloatHi)(val_1)/(FloatHi)(seq_len);
3264                 percent_2 = (FloatHi)(val_2)/(FloatHi)(seq_len);
3265                 
3266                 for(curr = gbp_list; curr !=NULL; curr = curr->next)
3267                 {
3268                         gbp = curr->data.ptrvalue;
3269                         bsp = gbp->bsp;
3270                         seq_len = bsp->length;
3271                         temp = percent_1 * (FloatHi)seq_len;
3272                         val_1 = (Int4)temp;
3273                         temp = percent_2 * (FloatHi)seq_len;
3274                         val_2 = (Int4)temp;
3275                                 
3276                         slp = load_seq_loc(val_1, val_2, seq_len, has_zero, bsp->id, &show_msg, add_interval);
3277                         if(slp != NULL)
3278                                 ValNodeAddPointer((Pointer)(&slp_list), 0, slp);
3279                 }
3280         }
3281         return slp_list;
3282 }
3283 
3284 
3285 /*********************************************************************
3286 *
3287 *
3288 *       find_map_pos(convert the start_pnt, stop_pnt into a list of 
3289 *       Seq-locs)
3290 *
3291 *********************************************************************/
3292 ValNodePtr find_map_pos(GlobalDrawPtr gdraw_p, PntInfo start_info, PntInfo stop_info)
3293 {
3294 
3295         Int4 val_1, val_2;
3296         ValNodePtr gbp_list; 
3297         PoinT center;
3298         ValNodePtr curr;
3299         GlobalBspPtr gbp;
3300         BioseqPtr bsp;
3301         Int4 seq_len;
3302         SeqLocPtr slp;
3303         ValNodePtr slp_list = NULL;
3304         Boolean show_msg = TRUE;
3305         Boolean add_interval;
3306         PoinT start_pnt, stop_pnt;
3307 
3308 
3309         if(gdraw_p == NULL)
3310                 return NULL;
3311         start_pnt.x = (Int2)(start_info.x);
3312         start_pnt.y = (Int2)(start_info.y);
3313         stop_pnt.x = (Int2)(stop_info.x);
3314         stop_pnt.y = (Int2)(stop_info.y);
3315         start_pnt.y = ABS(start_pnt.y);
3316         stop_pnt.y = ABS(stop_pnt.y);
3317 
3318         gbp_list = gdraw_p->gbp_list;
3319         center = gdraw_p->center;
3320         if(gdraw_p->is_circle)
3321                 return find_circle_pos(start_pnt, stop_pnt, gbp_list, center);
3322         
3323         add_interval = check_two_point(start_pnt, stop_pnt);
3324         for(curr = gbp_list; curr !=NULL; curr = curr->next)
3325         {
3326                 gbp = curr->data.ptrvalue;
3327                 bsp = gbp->bsp;
3328                 seq_len = bsp->length;
3329                 if(check_linear_pnt(start_pnt, stop_pnt, gbp->rec))
3330                 {
3331                         val_1 = convert_pnt_linear(start_pnt, gbp->rec, seq_len);
3332                         val_2 = convert_pnt_linear(stop_pnt, gbp->rec, seq_len);
3333                         slp = load_seq_loc(val_1, val_2, seq_len, FALSE, SeqIdFindBest(bsp->id, 0), &show_msg, add_interval);
3334                         if(slp != NULL)
3335                         ValNodeAddPointer((Pointer)&slp_list, (Uint1)(gbp->priority), slp);
3336                 }
3337         }
3338         return slp_list;
3339 }
3340 
3341 /*
3342 *
3343 *       if there is a Bioseq in the list that records the cytogenetic 
3344 *       band, return the Bioseq
3345 *
3346 */
3347 BioseqPtr has_cyto_map (GlobalDrawPtr gdraw_p)
3348 {
3349         ValNodePtr curr;
3350         GlobalBspPtr gbp;
3351 
3352         for(curr = gdraw_p->gbp_list; curr != NULL; curr = curr->next)
3353         {
3354                 gbp = curr->data.ptrvalue;
3355                 if(gbp->bsp != NULL && gbp->map_type == CYTO_MAP)
3356                         return gbp->bsp;
3357         }
3358         return NULL;
3359 }
3360 
3361 
3362 
3363 

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.