NCBI C Toolkit Cross Reference

C/desktop/dotvibrant.c


  1 /*   dotvibrant.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  6 *
  7 *  This software/database is a "United States Government Work" under the
  8 *  terms of the United States Copyright Act.  It was written as part of
  9 *  the author's official duties as a United States Government employee and
 10 *  thus cannot be copyrighted.  This software/database is freely available
 11 *  to the public for use. The National Library of Medicine and the U.S.
 12 *  Government do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 15 *
 16 *  Although all reasonable efforts have been taken to ensure the accuracy
 17 *  and reliability of the software and data, the NLM and the U.S.
 18 *  Government do not and cannot warrant the performance or results that
 19 *  may be obtained by using this software or data. The NLM and the U.S.
 20 *  Government disclaim all warranties, express or implied, including
 21 *  warranties of performance, merchantability or fitness for any particular
 22 *  purpose.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  dotvibrant.c
 27 *
 28 * Author:  Fasika Aklilu
 29 *
 30 * Version Creation Date:   8/8/01
 31 *
 32 * $Revision: 6.17 $
 33 *
 34 * File Description: mouse management, graphic engine of the sequence viewer
 35 *                   part of this code is also used for the WWW Entrez viewer
 36 *                   (WWW_UDV define)
 37 * Modifications:
 38 * --------------------------------------------------------------------------
 39 * $Log: dotvibrant.c,v $
 40 * Revision 6.17  2006/07/13 17:13:17  bollin
 41 * use Uint4 instead of Uint2 for itemID values
 42 *
 43 * Revision 6.16  2004/03/03 13:38:57  kans
 44 * removed unused end: labels
 45 *
 46 * Revision 6.15  2003/05/05 12:34:47  rsmith
 47 * type of DOTVibDataPtr displayOpts1 is Nlm_Handle, not HANDLE. Needed to compile under Codewarrior for Win32
 48 *
 49 * Revision 6.14  2002/08/07 18:14:23  kans
 50 * itemID is Uint4, minor cleanup
 51 *
 52 * Revision 6.13  2001/10/15 18:18:37  wheelan
 53 * adapted to new alignment manager
 54 *
 55 * Revision 6.12  2001/08/08 22:41:31  aklilu
 56 * added revision
 57 *
 58 * Revision 6.11  2000/10/31 22:39:14  vakatov
 59 * Get rid of the erroneous casts to HANDLE in the Nlm_Enable/Disable calls
 60 *
 61 * Revision 6.10  2000/08/07 16:34:51  kans
 62 * added public domain notice
 63 *
 64 Revision 6.9  2000/08/07 13:46:59  sicotte
 65 added revision
 66 
 67 Revision 6.8  2000/08/07 13:46:34  sicotte
 68 added revision
 69 
 70 Revision 6.7  2000/08/07 13:46:05  sicotte
 71 added Version logging
 72 
 73 Revision 6.6  2000/08/07 13:45:22  sicotte
 74 fixed (long) cast in sprintf and fprintf
 75 *
 76 *
 77 * ==========================================================================
 78 */
 79 /* dotvibrant.c */
 80 
 81 #include <dotviewer.h>
 82 #include <alignmgr2.h>
 83 
 84 
 85  /****************************************************************************
 86 
 87      DEFINES                                                            
 88  ***************************************************************************/
 89 
 90 #define MAXZOOMSCALEVAL 23
 91 #define BLOCK_SIZE 10
 92 #define VIS_LEN 100
 93 
 94 #define dot_SEQVIEW 1
 95 #define dot_FEATVIEW 2
 96 #define dotaln_BEST 1
 97 #define dotaln_OUTLYING_LARGE 2
 98 #define dotaln_OUTLYING_SMALL 3
 99 #define dotaln_GENERAL 4
100 #define dot_plot 1
101 #define align_plot 2
102 
103 
104 #define SHOW_MATCHES 1
105 #define SHOW_MISMATCHES 2
106 
107  /****************************************************************************
108 
109      GLOBAL VARIABLES                                                             
110  ***************************************************************************/
111 
112 static CharPtr  na_names[] = {"A", "C", "G", "T", "-"};
113 static CharPtr  aa_names [] =  {"-", "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W","X", "Y", "Z", "U" , "*"};
114 static Int4  zoomScaleVal [MAXZOOMSCALEVAL] = {
115   1L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 20L,
116   30L, 40L, 50L, 60L, 70L, 80L, 90L, 100L, 200L, 500L, 1000L
117 };
118 
119 Uint2  prev_primID = 0;
120 
121  /****************************************************************************
122 
123       FUNCTION DECLARATIONS                                                               
124  ***************************************************************************/
125 
126 static void DOT_DrawXAxis(SegmenT seg2, RecT  r, Int4 height, Int4 xstart,Int4 xstop, Int4 scale, SeqIdPtr sip);
127 static void DOT_DrawYAxis(SegmenT seg2, RecT  r, Int4 height, Int4 ystart, Int4 ystop, Int4 scale, Int4 Fh, SeqIdPtr sip);
128 static void DOT_VCrossHairs (RecT rcP, DOTVibDataPtr vdp, Int4 VFrom,Int4 HFrom);
129 static void DOT_HCrossHairs (RecT rcP, DOTVibDataPtr vdp, Int4 VFrom,Int4 HFrom);
130 static void DOT_QViewerClickProc(VieweR v, SegmenT seg, PoinT pt);
131 static void DOT_SViewerClickProc(VieweR v, SegmenT seg, PoinT pt);
132 static void DOT_ExitAlign(DOTAlignInfoPtr alp);
133 static DOTAlnPtr DOT_FindAlignment(DOTVibDataPtr vdp, Uint2 primID);
134 static Uint1Ptr DOT_GetNthSeqFromAlign (SeqAlignPtr sap, Int4 n);
135 static void DOT_SetColor(SegmenT  seg1, Int1 code, Boolean is_autopanel);
136 
137 /* scoop declarations */
138 extern void SCP_OrganizeAlnsInSet(SeqAlignPtr sap, Int4 fuzz, SCP_ResultPtr scp, Int4 n);
139 static int LIBCALLBACK SCP_CompareSpins(VoidPtr ptr1, VoidPtr ptr2);
140 static void SCP_GetNthSeqRangeInSASet(SeqAlignPtr PNTR saparray, Int4 numsaps, Int4 n, Int4Ptr start, Int4Ptr stop);
141 
142 /*_________________________________________(DOT_Compression)_____
143 
144   Purpose : Calculate sequence compression for window1
145 
146 ____________________________________________________________________*/
147 
148 Int4 DOT_Compression (Int4  len, Int4 viewersize)
149 {
150   Int4   cmpfactor;
151   double f;
152 
153   
154 
155       f = (double)(len/viewersize);
156       if (f <= 1)
157         cmpfactor = 1;
158       else
159         cmpfactor = (Int4)ceil(f);
160 
161       return cmpfactor;
162 
163 }
164 
165 /*_______________________________(DOT_SetupMenus)____________
166 
167   Purpose : Setup menus function for window1.
168 
169 ____________________________________________________________________*/
170 void DOT_SetupMenus ()
171 
172 {
173 #ifdef WIN_MAC
174   MenU    m;  
175 
176   m = AppleMenu (NULL);
177   DeskAccGroup (m);
178 #endif
179 
180 }
181 
182 
183 
184 /*________________________________(DOT_DrawXGrids)____________________
185 
186 
187   Purpose : Draw x-axis for DisplayHits, window1.
188 
189 ____________________________________________________________________*/
190 void DOT_DrawXGrids (RecT rupdate, RecT rcP, DOTVibDataPtr vdp, Int4 VFrom, Int4 HFrom, Int4 HTo, Int4 comp, Boolean GRID)
191 {
192   Int4         x, y, y2, offset=0;
193   Int4         scale_pos, pos, Hseq_pos;
194   Char         scale_buf[15] = {""};    /*scale value*/
195   
196 
197   offset=vdp->xstart;
198  
199   /* draw the axis no matter how short the length */
200 /*    if (vdp->curr_qlen <50) */
201 /*     return; */
202  
203   pos = 100;
204  /* select the font type */
205   SelectFont(vdp->Fnt);
206 
207   Black(); /* X axis */
208   MoveTo (rcP.left,rcP.top-10);
209   LineTo (rcP.left+ HTo,rcP.top-10);
210 
211 
212   /* write sequence length */
213   if ( vdp->curr_qlen - HFrom == HTo)
214     {
215 
216       Red();
217       sprintf(scale_buf, "%d", vdp->xstop);
218       MoveTo (rcP.left+ HTo +10 ,rcP.top-5);
219       PaintString (scale_buf);
220     }
221 
222   HTo += HFrom;
223   
224 
225       for (scale_pos = HFrom+1; scale_pos <= HTo+1; scale_pos++)
226         {
227           
228           /*  draw 0 on axis */
229           if (scale_pos == 1) 
230             { 
231               Black();
232               x =  rcP.left;
233               y =  rcP.top;
234               MoveTo (x, y-10);
235               LineTo (x,y-20);
236               Blue();
237               MoveTo(x,y -25);
238               sprintf(scale_buf, "%d", offset);
239               PaintString (scale_buf);
240               
241               
242             } 
243           else  
244             {
245               if (!(scale_pos % pos))
246                 {
247                   Hseq_pos = (scale_pos*comp)+offset;
248                   
249                   x = rcP.left + scale_pos-HFrom;
250                   y = MAX(rupdate.top, rcP.top);
251                   y2 = MIN(rupdate.bottom, rcP.top+vdp->curr_slen-VFrom);
252                   
253                   if ((!(HTo<rcP.left))&& (y<y2) && GRID)
254                     {
255                       LtGray();
256                       Dotted();
257                       MoveTo (x, y);
258                       LineTo (x,y2);  
259                     }
260                   
261                   /* add scale values */
262                   Black();
263                   Solid();
264                   y = rcP.top-10;
265                   MoveTo (x, y);
266                   LineTo (x,y-10);
267                   sprintf(scale_buf, "%d", Hseq_pos);
268                   x = rcP.left + scale_pos -HFrom - (StringWidth(scale_buf)/2);
269                   y = rcP.top -25;
270                   if (x>rcP.left)
271                     {
272                       Blue();
273                       MoveTo(x,y);
274                       PaintString (scale_buf);
275                     }
276                 }
277               else if (!(scale_pos % (pos/2)))
278                 {
279                   x = rcP.left + scale_pos -HFrom;
280                   y = rcP.top-10;
281                   MoveTo (x, y);
282                   LineTo (x,y-7);
283                   
284                 }
285               else if (!(scale_pos % (pos/10)))
286                 {
287                   Black();              
288                   x = rcP.left + scale_pos -HFrom;
289                   y = rcP.top-10;
290                   MoveTo (x, y);
291                   LineTo (x,y-5);
292                   
293                 }
294             }
295         }
296 
297 
298   Black();
299     
300     
301 }
302 
303 /*________________________________(DOT_DrawYGrids)____________________
304 
305   Purpose : Draw y-axis for DisplayHits, window1.
306 
307 ____________________________________________________________________*/
308 static void DOT_DrawYGrids (RecT rupdate, RecT rcP, DOTVibDataPtr vdp, Int4 VFrom, Int4 HFrom, Int4 VTo, Int4 comp, Boolean GRID)
309 {
310   Int4         x, y, x2, offset=0;
311   Int4         scale_pos, pos, Vseq_pos;
312   Char         scale_buf[15] = {""};    /*scale value*/
313   Int4         fh;
314   Boolean      Decrement = FALSE;
315   
316   offset=vdp->ystart;
317   
318   /* draw the axis no matter how short the length */
319 /*   if (vdp->curr_slen <50) */
320 /*     return; */
321 
322   pos = 100;
323 
324   SelectFont(vdp->Fnt);
325   fh = FontHeight();
326 
327   Black();
328   MoveTo (rcP.left-10,rcP.top);
329   LineTo (rcP.left-10,rcP.top+ VTo);
330 
331 
332   if (vdp->curr_slen - VFrom == VTo)
333     {
334       /* write the sequence length */
335       Red();
336       sprintf(scale_buf, "%d", vdp->ystop);
337       MoveTo (rcP.left-10 -(StringWidth(scale_buf)/2),rcP.top+ VTo +10 + (fh/2)); 
338       PaintString (scale_buf);
339     }
340 
341   VTo += VFrom;
342 
343   for (scale_pos = VFrom+1; scale_pos <= VTo+1; scale_pos++)
344     {
345       if (scale_pos == 1) 
346         {
347           Black();
348           x =  rcP.left-10;
349           y =  rcP.top;
350           MoveTo (x, y);
351           LineTo (x-10,y);
352           Blue();
353           sprintf(scale_buf, "%d", offset);
354           MoveTo(rcP.left-25-StringWidth(scale_buf),y+fh-4);
355           PaintString (scale_buf);
356         } 
357       else if (!(scale_pos % pos))
358         {
359           Vseq_pos = (!Decrement)?((scale_pos)*comp)+offset: offset - ((scale_pos)*comp);
360           
361           x = MAX(rupdate.left, rcP.left);
362           x2 = MIN(rupdate.right, rcP.left+vdp->curr_qlen-HFrom);
363           y = rcP.top -VFrom + scale_pos;
364          
365           /* draw vertical grid */
366           if ((scale_pos != 0) && (x<x2) && GRID)
367             {
368               LtGray();
369               Dotted(); 
370               MoveTo (x, y);
371               LineTo (x2,y);
372             }
373           /* add scale values */
374           Black(); 
375           Solid();
376           x = rcP.left -10;
377           MoveTo (x, y);
378           LineTo (x-10,y);
379           sprintf(scale_buf, "%d", Vseq_pos);
380           x = rcP.left -25 - StringWidth(scale_buf);
381           y = rcP.top-VFrom + scale_pos+ (fh/2);
382            
383           if (y-fh > rcP.top)
384             {
385                 Blue();
386                 MoveTo(x,y);
387                 PaintString (scale_buf);
388             }
389           
390         }
391       else if (!(scale_pos % (pos/2)))
392         {
393           Black(); 
394           x = rcP.left - 10;
395           y = rcP.top - VFrom + scale_pos;
396           MoveTo (x, y);
397           LineTo (x-7,y);
398         }
399       else if (!(scale_pos % (pos/10)))
400         {
401           Black();
402           x = rcP.left - 10;
403           y = rcP.top - VFrom + scale_pos;
404           MoveTo (x, y);
405           LineTo (x-5,y);
406         }
407     }
408   Black();
409 }
410 
411 
412 /*_______________________________________________(DOT_UpdateLRBT)________________
413 
414   Purpose : Computes Left, Right, Bottom and Top values for DisplayHits.
415 
416 ____________________________________________________________________*/
417 void DOT_UpdateLRBT (RecT r, RecT rcP, Int4Ptr Left, Int4Ptr Right, Int4Ptr Bottom, Int4Ptr Top)
418 {
419   
420   if (r.left > rcP.left)
421     *Left = r.left;
422   else
423     *Left = rcP.left;
424   
425   if (r.right < rcP.right)
426     *Right = r.right;
427   else
428     *Right = rcP.right;
429   
430   if (r.bottom < rcP.bottom)
431     *Bottom = r.bottom;
432   else
433     *Bottom = rcP.bottom;
434   
435   if (r.top > rcP.top)
436     *Top = r.top;
437   else
438     *Top = rcP.top;
439   
440   return;
441 }
442 /*________________________________________(DOT_AddRectMargins)_____________
443 
444   Purpose : Add horizontal and vertical margins to rect, window1.
445 
446 ____________________________________________________________________*/
447 static void DOT_AddRectMargins (RectPtr r, DOTVibDataPtr vdp)
448 {
449   r->left += vdp->HORZ_MARGIN;
450   r->top += vdp->VERT_MARGIN;
451 
452   return;
453 }
454 
455 /*____________________________________________(DOT_ChangeMainViewerCutoff)______
456 
457   Purpose : Change cutoff function for threshold-ramp, window1.
458 
459 ____________________________________________________________________*/
460 static void DOT_ChangeMainViewerCutoff (BaR b, GraphiC g, Int2 new, Int2 old) 
461 {
462   DOTVibDataPtr vdp;
463   WindoW     w, temport;
464   RecT       rcP;
465 
466   vdp = (DOTVibDataPtr) GetObjectExtra (b);
467 
468   Select(vdp->panel);
469   ObjectRect(vdp->panel, &rcP);
470   InsetRect(&rcP,4,4);
471 
472   w = (WindoW)ParentWindow(vdp->panel);
473   temport = SavePort(w);
474 
475   vdp->sdp.TrampPos = new+20;
476   
477   DOT_AddRectMargins(&rcP, vdp);
478   InvalRect (&rcP);
479   RestorePort (temport);
480   Update();
481 
482 }
483 
484 static PoinT curpnt;
485 static PoinT fstpnt;
486 
487 /*________________________________________(DOT_RectOverlpRect)_____________
488 
489   Purpose : Find overlapping region between two rects.
490 
491 ____________________________________________________________________*/
492 static Boolean DOT_RectOverlpRect (RectPtr r1, RectPtr r2)
493 {
494   if (r1->left <r2->left)
495     r1->left = r2->left;
496   if (r1->right >r2->right)
497     r1->right = r2->right;
498   if (r1->top < r2->top)
499     r1->top = r2->top;
500   if (r1->bottom > r2->bottom)
501     r1->bottom = r2->bottom;
502 
503   return TRUE;
504 }
505 
506 /*________________________________________(DOT_RectIntsRect)_____________
507 
508   Purpose : Checks if selected rect is in selectable rect, window1.
509 
510 ____________________________________________________________________*/
511 static Boolean DOT_RectIntsRect (RectPtr r1, RectPtr r2)
512 {
513   
514   if (r1->top > r2->bottom || r1->bottom < r2->top || r1->left > r2->right || r1->right < r2->left)
515     return FALSE;
516   else
517     return TRUE;
518 }
519 
520 /*________________________________________(DOT_LoopStop)_____________
521 
522   Purpose : calculate stop value in score_array for threshold-ramp.
523 
524 ____________________________________________________________________*/
525 static Int4 DOT_LoopStop (DOTVibDataPtr vdp)
526 {
527   Int4   stop;
528   Int4 pos;
529 
530   pos=(Int4)ceil((double)(vdp->sdp.TrampPos*vdp->mip->unique)/100);
531 
532   if (pos>=vdp->mip->unique)
533     return vdp->mip->index;
534   else
535     stop=vdp->mip->score_array[pos]+1;
536 
537   return stop;
538 }
539 
540 
541 /*_______________________________________________(DOT_DisplayHits)_________
542 
543 Purpose : Draw function for window1.
544 
545 ____________________________________________________________________*/
546 
547 static void DOT_DisplayHits (PaneL p)
548 {
549 
550   Int4           i, x, y, x2, y2;
551   RecT           rcP, rupd, rcS, rcs, dr, rcR, rcP_off;
552   Int4           comp, stop;
553   DOTVibDataPtr    vdp=NULL;
554   DOTMainDataPtr   mip=NULL;
555   DOTSelDataPtr      data;
556   WindoW         w;
557   Int4           VFrom, HFrom, VTo, HTo;
558   Boolean        query_on_minus = FALSE;
559   Boolean        q_hitonplus, s_hitonplus;
560   Int4           q_start, s_start, length;
561   Int4           ycomp, xcomp;
562   DOTDiagPtr     PNTR hitlist;
563   Int4           Left, Right, Bottom, Top;
564   Int2           dx, dy;
565   DOTAlnPtr      PNTR alnL;
566   DOTAlnPtr      aln;
567   Int4           q_left, q_right;
568   Int4           s_top, s_bottom;
569 
570   
571   w = (WindoW)ParentWindow(p);
572   rupd = updateRect;
573   ObjectRect(p, &rcP);
574   InsetRect(&rcP,4,4); 
575   ClipRect(&rcP);
576   
577   if (!(vdp = (DOTVibDataPtr)GetObjectExtra(w))) return;
578   
579   VFrom = vdp->sdp.VFrom; 
580   HFrom = vdp->sdp.HFrom;
581   VTo = (MIN (vdp->sdp.PgLen+VFrom, vdp->curr_slen-VFrom));
582   HTo = (MIN (vdp->sdp.PgWdth+HFrom, vdp->curr_qlen-HFrom));
583   
584   comp = vdp->comp;
585   
586   DOT_AddRectMargins (&rcP, vdp);
587   DOT_UpdateLRBT (rupd, rcP, &Left, &Right, &Bottom, &Top); 
588   mip = vdp->mip;
589   data = (DOTSelDataPtr)vdp->data;
590   if (vdp->selectMode == dot_FEATVIEW)
591     {
592       if(data->selected)
593         {
594           DOT_VCrossHairs (rcP, vdp, VFrom, HFrom);
595           DOT_HCrossHairs (rcP, vdp, VFrom, HFrom);
596         }
597     }
598   else
599     {
600   if (data->selected) 
601     {
602       rcs=data->rcS;
603       
604       dx=HFrom-data->H_pos;
605       dy=VFrom-data->V_pos;
606       
607       xcomp=vdp->originalcomp-comp;
608       ycomp=xcomp;
609  
610       rcS.left=rcs.left-dx;
611       rcS.right=rcs.right-dx;
612       rcS.top=rcs.top-dy;
613       rcS.bottom=rcs.bottom-dy;
614    
615       rcR.left = Left;
616       rcR.right = Right;      
617       rcR.top = Top;
618       rcR.bottom = Bottom;
619       
620       if (DOT_RectIntsRect(&rcS, &rcR))
621         {
622           rcP_off = rcP;
623           DOT_RectOverlpRect(&rcS, &rcR);
624           SectRect (&rcS, &rcP_off, &dr);
625           Yellow();
626           PaintRect (&dr);
627           Black();
628         }
629     }
630     }
631   DOT_DrawXGrids(rupd, rcP, vdp, VFrom, HFrom, HTo, comp, vdp->showGrid);
632   DOT_DrawYGrids(rupd, rcP, vdp, VFrom, HFrom, VTo, comp, vdp->showGrid);
633   
634   if (vdp->showDotPlot && mip)
635     {
636       hitlist = mip->hitlist;
637       if (mip->unique<=1)
638         stop = mip->index;
639       else
640         stop = DOT_LoopStop (vdp);
641 
642       if (vdp->strand1 == Seq_strand_minus)
643         query_on_minus = TRUE;
644 
645       for (i = 0; i<stop ; i++)
646         {       
647           length = hitlist[i]->length;
648 
649           if (query_on_minus)
650             q_start = mip->q_stop - hitlist[i]->q_start;
651           else
652             q_start = hitlist[i]->q_start - mip->q_start;
653           s_start = hitlist[i]->s_start - mip->s_start;
654           q_start = ((int)q_start/comp)-HFrom;
655           s_start = ((int)s_start/comp)-VFrom;
656           length = (int)length/comp; 
657 
658           if (query_on_minus){
659             x = rcP.left + q_start;
660             x2 = x - length;
661             q_left = x2;
662             q_right = x;
663           }
664           else {
665             x = rcP.left + q_start;
666             x2 = x + length;
667             q_left = x;
668             q_right = x2;
669           }
670 
671           y = rcP.top +  s_start;
672           y2 = y + length; 
673           
674           if (y > Bottom || y2 < Top  || q_left > Right || q_right < Left) 
675             continue; /* outside of drawing Rgn */
676           
677           if (query_on_minus){ 
678             if (q_left < rcP.left)
679               { 
680                 y2 = y2 - (rcP.left - q_left);
681                 q_left = rcP.left; 
682               } 
683           }
684           else { 
685             if (q_left < rcP.left) { 
686               y = y - (rcP.left - q_left); 
687               q_left = rcP.left;
688             }
689           }
690 
691           if (y < rcP.top) {
692             q_left = q_left - (rcP.top - y);
693             y = rcP.top; 
694           } 
695  
696           if (y < rcP.top) 
697             {
698               q_left = q_left + (rcP.top-y);
699               y = rcP.top;
700             } 
701           
702           if (q_left < rcP.left)
703             { 
704               y = y+(rcP.left-q_left);  
705               q_left = rcP.left; 
706             }
707           
708           if (query_on_minus)
709             x2 = q_left; 
710           else  
711             x = q_left;
712           
713           MoveTo(x, y);
714           LineTo(x2, y2);
715           
716         }
717     }
718 
719   if (vdp->showALIGN && vdp->alp) /* overlay Blast hits */
720     {
721       Red();
722       alnL = vdp->alp->Alnlist;
723       stop = vdp->alp->index;
724       for (i = 0; i<stop; i++)
725         {
726           aln = alnL[i];
727 
728           q_start=ABS(vdp->xstart - aln->q_start);
729           s_start=ABS(vdp->ystart - aln->s_start);
730           q_start=q_start/comp - HFrom;
731           s_start=s_start/comp - VFrom;
732           length = ABS(aln->q_stop - aln->q_start)+1;
733           length = length/comp;
734 
735           if (vdp->strand1==Seq_strand_minus){
736             q_hitonplus=FALSE;
737             x = rcP.left + q_start;
738             x2 = x - length;
739             q_left = x2;
740             q_right = x;
741           }
742           else{
743             q_hitonplus=TRUE;
744             x = rcP.left + q_start;
745             x2 = x + length;
746             q_left = x;
747             q_right = x2;
748           }
749 
750           if (vdp->strand2==Seq_strand_minus){
751             s_hitonplus=FALSE;
752             y = rcP.top + s_start;
753             y2 = y - length;
754             s_top = y2;
755             s_bottom = y;
756           }
757           else {
758             s_hitonplus=TRUE;
759             y=rcP.top+s_start;
760             y2=y+length;
761             s_top = y;
762             s_bottom = y2;
763           }
764          
765           if (q_left > Right || q_right < Left ||
766               s_top > Bottom || s_bottom < Top)
767             continue;
768 
769           if (q_hitonplus==s_hitonplus){
770             if (x<rcP.left)
771               {
772                 y=y+(rcP.left-x);
773                 x=rcP.left;
774               }
775             if (y < rcP.top) 
776               {
777                 x = x+(rcP.top-y);
778                 y=rcP.top;
779               }
780           }
781           else{
782             if (q_hitonplus){ /* s is minus */
783               if (x< rcP.left)
784                 {
785                   y = y-(rcP.left-x); 
786                   x = rcP.left;
787                 }
788             }
789             else { /* q is on minus strand */
790               if (x2< rcP.left)
791                 {
792                   y2=y2-(rcP.left-x2);
793                   x2 = rcP.left;
794                 }
795             }
796             if (s_hitonplus){ /* q is minus */
797               if (y < rcP.top) 
798                 {
799                   x = x-(rcP.top-y);
800                   y=rcP.top;
801                 }
802             }
803             else {/* s is on minus strand */
804               if (y2 < rcP.top) 
805                 {
806                   x2=x2-(rcP.top-y2);
807                   y2=rcP.top;
808                 }
809             }
810           }
811           DOT_SetColor(NULL, aln->class, TRUE);
812           MoveTo(x, y);
813           LineTo(x2, y2);
814         }
815       Black();
816     }
817   
818   ResetClip();
819   return;
820 }
821 
822 
823 /*________________________________________(DOT_SetCurrSeqlen)_____________
824 
825 
826   Purpose : Update displayed seq-length after reduce/enlarge functions.
827 
828 ____________________________________________________________________*/
829   /*set the current size of the sequence display */
830 static void DOT_SetCurrSeqlen (DOTVibDataPtr vdp)
831 {
832   Int4 comp;
833   
834   comp = vdp->comp;
835 
836     vdp->curr_slen = (vdp->ylen)/comp;
837     vdp->curr_qlen = (vdp->xlen)/comp;
838 
839 }
840 
841 
842 /*________________________________________(DOT_VScrlUpdate)_____________
843 
844   Purpose : Update function for vertical scroll proc, window1.
845 
846 ____________________________________________________________________*/
847 
848 static void DOT_VScrlUpdate(DOTVibDataPtr vdp, BaR vsb, Int4 VCurPos)
849 {
850 
851   VCurPos = VCurPos*vdp->sdp.UnitY;
852 
853   /*set cursor position to new Units */
854   VCurPos = VCurPos/vdp->sdp.UnitY;
855 
856   if (VCurPos<0) VCurPos=0;
857   
858   if (VCurPos >= vdp->sdp.YScrlMax)
859     vdp->sdp.YScrlPos = vdp->sdp.YScrlMax;
860   else 
861     vdp->sdp.YScrlPos = VCurPos;
862   
863   vdp->sdp.VFrom=vdp->sdp.YScrlPos*vdp->sdp.UnitY;
864 
865   /*update scroll*/
866   CorrectBarMax(vsb, vdp->sdp.YScrlMax);
867   CorrectBarValue(vsb, vdp->sdp.YScrlPos);
868   CorrectBarPage(vsb, vdp->sdp.YScrlPage, vdp->sdp.YScrlPage);
869   
870 }
871 
872 
873 /*________________________________________(DOT_HScrlUpdate)_____________
874 
875   Purpose : Update function for horizontal scroll proc.
876 
877 ____________________________________________________________________*/
878 
879 static void DOT_HScrlUpdate(DOTVibDataPtr vdp, BaR hsb, Int4 HCurPos)
880 {  
881   HCurPos = HCurPos*vdp->sdp.UnitX;
882 
883   /*set cursor position to new Units */
884   HCurPos = HCurPos/vdp->sdp.UnitX;
885 
886   if (HCurPos<0) HCurPos=0;
887   
888   if (HCurPos >= vdp->sdp.XScrlMax)
889     vdp->sdp.XScrlPos = vdp->sdp.XScrlMax;
890   else 
891     vdp->sdp.XScrlPos = HCurPos;
892   
893   vdp->sdp.HFrom=vdp->sdp.XScrlPos*vdp->sdp.UnitX;
894 
895   /*update scroll*/
896   CorrectBarMax(hsb, vdp->sdp.XScrlMax);
897   CorrectBarValue(hsb, vdp->sdp.XScrlPos);
898   CorrectBarPage(hsb, vdp->sdp.XScrlPage, vdp->sdp.XScrlPage);
899   
900 }
901 
902 
903 
904 /*________________________________________________(DOT_VscrlProc)_____________
905 
906   Purpose : Vertical Scroll proc, window1.
907 
908 ____________________________________________________________________*/
909 static void DOT_VscrlProc (BaR vsb, SlatE s, Int2 newval, Int2 oldval)
910 {
911   WindoW                temport, w;
912   DOTVibDataPtr   vdp;
913   RecT         rcP;
914   Int2         dy, offset;
915   Int2         visLines, vmargin, hmargin;
916   PaneL        p;
917 
918 
919   w = (WindoW)ParentWindow((PaneL)s);
920   vdp = (DOTVibDataPtr)GetObjectExtra (w);
921   p = vdp->panel;
922   
923   offset=vdp->sdp.HFrom;
924   vmargin=vdp->VERT_MARGIN;
925   hmargin=vdp->HORZ_MARGIN;
926 
927   temport = SavePort (w);
928 
929   Select(p);
930   ObjectRect(p, &rcP);
931   InsetRect(&rcP, 4, 4);
932   ClipRect(&rcP);
933 
934   vdp->sdp.YScrlPos = newval;
935   visLines = vdp->sdp.YScrlPage;
936   vdp->sdp.VFrom=newval*vdp->sdp.UnitY;
937 
938   rcP.right = (MIN (rcP.left+hmargin+vdp->curr_qlen-offset, rcP.right));
939   rcP.top += vmargin;
940 
941   dy = newval- oldval;
942   if (ABS(dy) < vdp->sdp.YScrlPage)
943     {
944       ScrollRect(&rcP,  0, (Int2)((-dy)*vdp->sdp.UnitY));
945     }
946   else
947     {
948       InsetRect(&rcP, -1, -1);
949       InvalRect(&rcP);
950     }
951   ResetClip();
952   RestorePort(temport);
953 /*   Update(); */
954   
955 }
956 
957 
958 
959 /*________________________________________________(DOT_HscrlProc)_____________
960 
961   Purpose : Horizontal scroll proc, window1.
962 
963 ____________________________________________________________________*/
964 static void DOT_HscrlProc (BaR Hsb, SlatE s, Int2 newval, Int2 oldval)
965 {
966   WindoW                temport, w;
967   DOTVibDataPtr   vdp;
968   RecT         rcP;
969   Int2         dx, visLines, offset, hmargin, vmargin;
970 
971   
972   w = (WindoW)ParentWindow((PaneL)s);
973   vdp = (DOTVibDataPtr)GetObjectExtra (w);
974 
975   temport = SavePort (w);
976   Select(vdp->panel);
977   ObjectRect(vdp->panel, &rcP);
978   InsetRect(&rcP, 4, 4);
979   ClipRect (&rcP);
980 
981   offset=vdp->sdp.VFrom;
982   hmargin=vdp->HORZ_MARGIN;
983   vmargin=vdp->VERT_MARGIN;
984 
985   rcP.bottom = (MIN (rcP.top+vmargin+vdp->curr_slen-offset, rcP.bottom));
986   rcP.left += hmargin;
987 
988   vdp->sdp.XScrlPos = newval;
989   visLines = vdp->sdp.XScrlPage;
990   vdp->sdp.HFrom=newval*vdp->sdp.UnitX;
991 
992   dx = newval - oldval;
993 
994   if (ABS(dx) < vdp->sdp.XScrlPage)
995     {
996       ScrollRect(&rcP, (Int2)((-dx)*vdp->sdp.UnitX) , 0);
997     }
998   else
999     {
1000       InsetRect(&rcP, -1, -1);
1001       InvalRect(&rcP);
1002     }
1003   
1004   ResetClip();
1005   RestorePort(temport);
1006 /*   Update(); */
1007   
1008 }
1009 
1010 
1011 /*________________________________________(DOT_UpdateMainPanel)_____________
1012 
1013   Purpose : Update selection for window1.
1014 
1015 ____________________________________________________________________*/
1016 
1017 static void DOT_UpdateMainPanel(DOTVibDataPtr vdp, Boolean update_all)
1018 {
1019   WindoW     temport;
1020   RecT       rc;
1021   DOTSelDataPtr  data;
1022   Int4           dx, dy;
1023 
1024   data=(DOTSelDataPtr)vdp->data;
1025 
1026   temport = SavePort((WindoW)ParentWindow(vdp->panel));
1027   Select(vdp->panel);
1028   ObjectRect(vdp->panel, &rc);
1029   ClipRect(&rc);
1030   
1031   if (!update_all)
1032     {
1033       if (data->rm_lastselected)
1034         { 
1035           InsetRect(&data->old_rcS, -1, -1);
1036           InvalRect(&data->old_rcS);
1037           data->rm_lastselected=FALSE;
1038         }
1039       dx=data->H_pos-vdp->sdp.HFrom;
1040       dy=data->V_pos-vdp->sdp.VFrom;
1041       rc.left=data->rcS.left-dx;
1042       rc.right=data->rcS.right-dx;
1043       rc.top=data->rcS.top-dy;
1044       rc.bottom=data->rcS.bottom-dy;
1045       InsetRect(&rc, -1, -1);
1046       InvalRect (&rc);
1047     }
1048   else
1049     {
1050       InsetRect(&rc, -1, -1);
1051       InvalRect(&rc);
1052     }
1053 
1054   ResetClip();
1055   RestorePort(temport);
1056   Update();
1057 
1058 }
1059 
1060 
1061 /*______________________________________(DOT_VScroll)___________
1062 
1063   Purpose : Correct vertical scroll bar values, window1.
1064 
1065 ____________________________________________________________________*/
1066 static void DOT_VScroll (DOTVibDataPtr vdp, BaR vsb)
1067 {
1068  
1069   CorrectBarMax(vsb,vdp->sdp.YScrlMax);
1070   CorrectBarValue(vsb,vdp->sdp.YScrlPos);
1071   CorrectBarPage(vsb, vdp->sdp.YScrlPage, vdp->sdp.YScrlPage);
1072 
1073 }
1074 /*______________________________________(DOT_HScroll)___________
1075 
1076   Purpose : Correct horizontal scroll bar values, window1.
1077 
1078 ____________________________________________________________________*/
1079 static void DOT_HScroll (DOTVibDataPtr vdp, BaR hsb)
1080 {
1081 
1082   CorrectBarMax(hsb,vdp->sdp.XScrlMax);
1083   CorrectBarValue(hsb,vdp->sdp.XScrlPos);
1084   CorrectBarPage(hsb,vdp->sdp.XScrlPage, vdp->sdp.XScrlPage);
1085 
1086 }
1087 /*________________________________________(DOT_ComputePanelSize)_____________
1088 
1089   Purpose : Calculate panel size for scrolling functions, window1.
1090 
1091 ____________________________________________________________________*/
1092 static void DOT_ComputePanelSize (RecT rcP, DOTVibDataPtr vdp, Int4Ptr PgWdth, Int4Ptr PgLen)
1093 {
1094 
1095   InsetRect(&rcP, 4, 4);
1096   rcP.left += vdp->HORZ_MARGIN;
1097   rcP.top += vdp->VERT_MARGIN;
1098 
1099   *PgWdth =rcP.right-rcP.left;
1100   *PgLen  =rcP.bottom-rcP.top;
1101 
1102 }
1103 
1104 /*________________________________________(DOT_SetScrlVals)_____________
1105 
1106   Purpose : Set scroll values for window1.
1107 
1108 ____________________________________________________________________*/
1109 static void DOT_SetScrlVals (DOTVibDataPtr vdp)
1110 {
1111 /*   Int4  scrollfctr = 40; */
1112 
1113 /*   vdp->sdp.UnitY = vdp->sdp.PgLen/scrollfctr; */
1114   vdp->sdp.UnitY = 16; /*  constant value*/
1115   vdp->sdp.TotUnitsY = vdp->curr_slen/vdp->sdp.UnitY;
1116   vdp->sdp.YScrlPage = vdp->sdp.PgLen/vdp->sdp.UnitY;
1117   vdp->sdp.YScrlMax = vdp->sdp.TotUnitsY-(vdp->sdp.YScrlPage - vdp->VERT_MARGIN/vdp->sdp.UnitY);
1118 
1119 /*   vdp->sdp.UnitX = vdp->sdp.PgWdth/scrollfctr; */
1120   vdp->sdp.UnitX = 16;/*  constant value*/
1121   vdp->sdp.TotUnitsX = vdp->curr_qlen/vdp->sdp.UnitY;
1122   vdp->sdp.XScrlPage = vdp->sdp.PgWdth/vdp->sdp.UnitX;
1123   vdp->sdp.XScrlMax = vdp->sdp.TotUnitsX-(vdp->sdp.XScrlPage - vdp->HORZ_MARGIN/vdp->sdp.UnitX);
1124 
1125   /* image is smaller than page size */
1126   if ((vdp->sdp.YScrlPage + vdp->HORZ_MARGIN/vdp->sdp.UnitX) > vdp->sdp.TotUnitsY)
1127     {
1128       vdp->sdp.YScrlMax = 0;
1129       vdp->sdp.YScrlPage = 0;
1130       vdp->sdp.YScrlPos = 0;
1131     }
1132   if (vdp->sdp.XScrlPage>vdp->sdp.TotUnitsX)
1133     {
1134       vdp->sdp.XScrlMax = 0;
1135       vdp->sdp.XScrlPage = 0;
1136       vdp->sdp.XScrlPos = 0;
1137     }
1138  
1139 }
1140 
1141 /*______________________________________(DOT_SetUpWin)___________
1142 
1143   Purpose : Scrolling info setup function for window1.
1144 
1145 ____________________________________________________________________*/
1146 static void DOT_SetUpWin(WindoW w, PaneL p, DOTVibDataPtr vdp)
1147 {
1148 
1149   Int4       height, width, viewersize, len;
1150   Int4       gap, lmargin, vsbWidth, hsbHeight;
1151   BaR        vsb, hsb;
1152   WindoW     temport;
1153   RecT       rcP, rcW, rcHsb, rcVsb;
1154 
1155 
1156 
1157   temport = SavePort (w);
1158   Select(p);
1159   ObjectRect(p, &rcP);
1160 
1161  /* Reset Panel Parameters */
1162   ObjectRect(w, &rcW);
1163   width = rcW.right-rcW.left;
1164   height = rcW.bottom-rcW.top;
1165   vsb = GetSlateVScrollBar ((SlatE) p);
1166   hsb = GetSlateHScrollBar ((SlatE) p);
1167   
1168   GetPosition(vsb,&rcVsb);
1169   GetPosition(hsb,&rcHsb);
1170 
1171   gap=2;
1172   lmargin=10;
1173   vsbWidth=rcVsb.right-rcVsb.left;
1174   hsbHeight=rcHsb.bottom-rcHsb.top;
1175     
1176   rcP.right = width - vsbWidth - gap;
1177   rcP.bottom = height - hsbHeight - gap;
1178   rcP.left=lmargin;
1179 
1180   SetPosition (vdp->panel, &rcP);
1181   AdjustPrnt (vdp->panel, &rcP, FALSE);
1182 
1183   viewersize=MIN(rcP.right-rcP.left,rcP.bottom-rcP.top)-vdp->HORZ_MARGIN;
1184   len=MAX(vdp->xlen, vdp->ylen);
1185   vdp->comp=DOT_Compression(len, viewersize);
1186   vdp->originalcomp=vdp->comp;
1187  
1188 
1189   vdp->sdp.YScrlPos = 0;
1190   vdp->sdp.XScrlPos = 0;
1191 
1192   DOT_SetCurrSeqlen (vdp);
1193   DOT_ComputePanelSize(rcP, vdp, &(vdp->sdp.PgWdth), &(vdp->sdp.PgLen));
1194   DOT_SetScrlVals(vdp);
1195 
1196   DOT_VScroll (vdp, vsb);
1197   DOT_HScroll (vdp, hsb);
1198 
1199   RestorePort(temport);
1200 
1201 }
1202 
1203 
1204 
1205 
1206 /*________________________________________(DOT_CloseSequenceWindow)_____________
1207 
1208   Purpose : Close function for Sequence Window.
1209 
1210 ____________________________________________________________________*/
1211 static void  DOT_CloseSequenceWindow (ButtoN b)
1212 {
1213 
1214   DOTVibDataPtr vdp2, vdp;
1215   DOTSelDataPtr  data;
1216 
1217   vdp2=(DOTVibDataPtr)GetObjectExtra(ParentWindow(b));
1218 
1219   data=(DOTSelDataPtr)vdp2->data;
1220   data->selected=FALSE;
1221   vdp=data->vdp;
1222   SetTitle(vdp->Infopanel, vdp->iInfo);
1223 
1224   DOT_UpdateMainPanel(vdp, FALSE);
1225  
1226   vdp2->sv->pict1=DeletePicture(vdp2->sv->pict1);
1227   vdp2->sv->pict2=DeletePicture(vdp2->sv->pict2);
1228   
1229   if (vdp2->sv->salp)
1230     MemFree(vdp2->sv->salp);
1231   if (vdp2->sv) MemFree(vdp2->sv);
1232   if (vdp2->mip){
1233     DOT_FreeMainInfo(vdp2->mip);
1234     if (vdp2->mip) MemFree(vdp2->mip);
1235   }
1236   if (vdp2) MemFree(vdp2);
1237   Remove (vdp->ChildWin);
1238   vdp->ChildWin=NULL;
1239 
1240   prev_primID = 0;
1241 }
1242 
1243 
1244 
1245 /*_____________________________________________________________________
1246 
1247   Purpose : Remove feature linked list
1248 
1249 ____________________________________________________________________*/
1250 static void DOT_FreeFeatPointers(DOTRowPtr drp)
1251 {
1252   DOTFeatPtr dfp_temp=NULL, dfp=NULL;
1253 
1254   dfp=drp->dfp;
1255   if (dfp == NULL) return;
1256   dfp_temp=dfp;
1257   dfp=dfp->next;
1258   while(dfp != NULL)
1259     {
1260       dfp_temp=MemFree(dfp_temp);
1261       dfp_temp = dfp;
1262       dfp = dfp->next;
1263     }
1264   if (dfp_temp!=NULL) MemFree(dfp_temp);
1265 
1266 }
1267 
1268 /*________________________________________(DOT_CloseFeatWindow)_____________
1269 
1270   Purpose : Close function for Feature Window.
1271 
1272 ____________________________________________________________________*/
1273 static void  DOT_CloseFeatWindow (IteM i)
1274 {
1275   DOTFeatListPtr flp;
1276   DOTSelDataPtr  data;
1277 
1278 
1279       flp=(DOTFeatListPtr)GetObjectExtra(ParentWindow(i));
1280       if (!flp) return;
1281 
1282       data=(DOTSelDataPtr)flp->data;
1283       data->selected=FALSE;
1284       DOT_UpdateMainPanel(data->vdp, TRUE);
1285 
1286       flp->segQuery=DeletePicture(flp->segQuery);
1287       flp->segSubject=DeletePicture(flp->segSubject);
1288       DOT_FreeFeatPointers(flp->query_drp);
1289       DOT_FreeFeatPointers(flp->subject_drp);
1290       if (flp->featindex) flp->featindex=MemFree(flp->featindex);
1291       if (flp->query_drp) flp->query_drp=MemFree(flp->query_drp);
1292       if (flp->subject_drp)flp->subject_drp=MemFree(flp->subject_drp);
1293       if (flp->FeatWin) flp->FeatWin=Remove (flp->FeatWin);
1294       data->vdp->ChildWin=NULL;
1295       if (flp) flp=MemFree(flp);
1296      
1297 }
1298 
1299 /*_____________________________________________________________________
1300 
1301   Purpose : Remove 'sequence' or 'feature' window
1302 
1303 ____________________________________________________________________*/
1304 
1305 static WindoW DOT_ClearLastWindow(WindoW w, Boolean is_sequence)
1306 {
1307   DOTVibDataPtr vdp;
1308   DOTFeatListPtr flp;
1309   DOTSelDataPtr  data;
1310 
1311   if (!w) return w;
1312 
1313   if (is_sequence)
1314     {
1315       vdp=(DOTVibDataPtr)GetObjectExtra(w);
1316       if (!vdp) return w;
1317 
1318       data=(DOTSelDataPtr)vdp->data;
1319       data->selected=FALSE;
1320 
1321       if(vdp->sv->v1) DeleteViewer(vdp->sv->v1);
1322       if(vdp->sv->v2) DeleteViewer(vdp->sv->v2);
1323       if(vdp->sv->pict1) DeletePicture(vdp->sv->pict1);
1324       if(vdp->sv->pict2) DeletePicture(vdp->sv->pict2);
1325       vdp->sv=MemFree(vdp->sv);
1326 
1327 /*       if (vdp->mip)  */
1328 /*         { */
1329 /*           DOT_FreeMainInfo(vdp->mip); */
1330 /*           MemFree(vdp->mip); */
1331 /*         } */
1332 
1333     }
1334   else
1335     {
1336       flp=(DOTFeatListPtr)GetObjectExtra(w);
1337       if (!flp) return w;
1338 
1339       data=(DOTSelDataPtr)flp->data;
1340       data->selected=FALSE;
1341 
1342       DeletePicture(flp->segQuery);
1343       DeletePicture(flp->segSubject);
1344      /*  DOT_FreeFeatPointers(flp->query_drp); */
1345 /*       DOT_FreeFeatPointers(flp->subject_drp); */
1346 /*       MemFree(flp->query_drp); */
1347 /*       MemFree(flp->subject_drp); */
1348       MemFree(flp);
1349     }
1350 
1351   DOT_UpdateMainPanel(data->vdp, TRUE);
1352 
1353   w=Remove(w);
1354 
1355   return NULL;
1356  
1357 }
1358 /*_____________________________________________________________________
1359 
1360   Purpose : New set of function to show features on dotviewer
1361 
1362 ____________________________________________________________________*/
1363 
1364 static void DOT_ModeProc(ChoicE i)
1365 {
1366   WindoW      w, temport;
1367   RecT        rcP;
1368   DOTVibDataPtr  vdp;
1369   DOTSelDataPtr  data;
1370   
1371 
1372   w = (WindoW)ParentWindow(i);
1373   temport=SavePort(w);
1374   vdp = (DOTVibDataPtr)GetObjectExtra (w);
1375   if (!vdp) return;
1376 
1377   if (vdp->ChildWin !=NULL)
1378     {
1379       if (vdp->selectMode == 1)
1380         vdp->ChildWin=DOT_ClearLastWindow(vdp->ChildWin, TRUE);
1381       else
1382         vdp->ChildWin=DOT_ClearLastWindow(vdp->ChildWin, FALSE);
1383     }
1384 
1385   vdp->selectMode = GetValue(i);
1386   data=(DOTSelDataPtr)vdp->data;
1387   data->selected=FALSE;
1388   ObjectRect(vdp->panel, &rcP);
1389   Select(vdp->panel);
1390   InvalRect(&rcP);
1391   RestorePort(temport);
1392   Update();
1393 
1394 }
1395 
1396 static void DOT_VCrossHairs (RecT rcP, DOTVibDataPtr vdp, Int4 VFrom,Int4 HFrom)
1397 {
1398   Int4   y, y2, x, x2;
1399   Int4   cursor_size =15;
1400 /*   SelectPtr c_data; */
1401 
1402 /*   c_data = cip->data; */
1403 
1404   /* vertical line */
1405   y = rcP.top-vdp->VERT_MARGIN+20;
1406   y2= rcP.bottom-1/* MIN(rcP.bottom - 1 , VTo) */;
1407   x2 = x = curpnt.x/* +HFrom */;
1408 /*   x2 = x = rcP.left +c_h.x -cip->HORZ_MARGIN - cursor_size; */
1409   if (x>=rcP.left)
1410     {
1411       Magenta();
1412       MoveTo (x, y);
1413       LineTo (x2, y2);
1414 
1415     }
1416   Black();
1417   return;
1418   
1419 }
1420 
1421 static void DOT_HCrossHairs (RecT rcP, DOTVibDataPtr vdp, Int4 VFrom,Int4 HFrom)
1422 {
1423   Int4  y, y2, x, x2;
1424   Int4  cursor_size = 15;
1425 /*   SelectPtr  c_data; */
1426 
1427 /*   data = vdp->data; */
1428 
1429   /* horizontal line */
1430     y2 = y = curpnt.y /* + VFrom */;
1431 /*   y2 = y = rcP.top + c_h.y  -cip->VERT_MARGIN - cursor_size; */
1432   x = rcP.left-vdp->HORZ_MARGIN+20;
1433   x2 = rcP.right-1/* MIN(rcP.right -1, HTo) */;
1434   if (y>=rcP.top)
1435     {
1436       Magenta ();
1437       MoveTo(x, y);
1438       LineTo (x2, y2);
1439     }
1440   Black();
1441   return;
1442   
1443 }
1444 
1445 
1446 static void DOT_MoveCrossHairs (RecT rcP, DOTVibDataPtr vdp)
1447 {
1448   Int4   y, y2, x, x2;
1449   Int4   cursor_size = 15;
1450   DOTSelDataPtr  data;
1451 
1452   SelectFont(vdp->Fnt);
1453 
1454   data = (DOTSelDataPtr) vdp->data;
1455   DOT_AddRectMargins(&rcP, vdp);
1456 
1457   /* vertical line */
1458   y = rcP.top-vdp->VERT_MARGIN+20;
1459   y2= rcP.bottom-1;
1460   x2 = x = curpnt.x;
1461   if (x>rcP.left)
1462     {
1463       MoveTo (x, y);
1464       LineTo (x2, y2);
1465     }
1466 
1467   /* horizontal line */
1468   y2 = y = curpnt.y;
1469   x = rcP.left-vdp->HORZ_MARGIN +20;
1470   x2 = rcP.right-1;
1471   if (y>rcP.top)
1472     {
1473       MoveTo(x, y);
1474       LineTo (x2, y2);
1475 
1476     }
1477 
1478   Black();
1479 
1480 
1481   return;
1482   
1483 }
1484 
1485 
1486 static void DOT_SelectLineProc (PaneL p)
1487 
1488 {
1489   RecT        rcP;
1490   DOTVibDataPtr  vdp;
1491 
1492   vdp = (DOTVibDataPtr) GetObjectExtra (ParentWindow(p));
1493   Dotted ();
1494   ObjectRect (p, &rcP);
1495   InsetRect (&rcP, 4, 4);
1496   DOT_MoveCrossHairs (rcP, vdp); 
1497 }
1498 
1499 
1500 /*________________________________________(DOT_SelectFrameProc)_____________
1501 
1502   Purpose : select frame for click and drag functions of window1.
1503 
1504 ____________________________________________________________________*/
1505 static void DOT_SelectFrameProc (PaneL p)
1506 
1507 {
1508   RecT  dr;
1509   RecT  or;
1510   RecT  r;
1511 
1512   Dotted ();
1513   ObjectRect (p, &or);
1514   InsetRect (&or, 2, 2);
1515   LoadRect (&r, fstpnt.x, fstpnt.y, curpnt.x, curpnt.y);
1516   SectRect (&r, &or, &dr);
1517   FrameRect (&dr);
1518   
1519 }
1520 
1521 /*________________________________________(DOT_DrawXAxis)_____________
1522 
1523   Purpose : Draw x-axis function for viewer1, window2.
1524 
1525 ____________________________________________________________________*/
1526 void DOT_DrawXAxis(SegmenT seg2, RecT  r, Int4 height, Int4 xstart,Int4 xstop, Int4 scale, SeqIdPtr sip)
1527 {
1528   Int4         pos, xlen, x, y, scale_pos, i, j, bigtick, midtick, smalltick;
1529   Char         scale_buf[15] = {""}, title[50]={""};    /*scale value*/
1530   Boolean      Decrement=FALSE;
1531 
1532 
1533   if (xstart>xstop)
1534     Decrement=TRUE;
1535 
1536   if (scale==0)
1537     scale=1;
1538 
1539   pos=100*scale;
1540   bigtick=10*scale;
1541   midtick=7*scale;
1542   smalltick=5*scale;
1543  
1544 
1545   xlen=ABS(xstop-xstart);
1546 
1547   /* axis label */ 
1548 /*   SeqIdWrite(sip, title ,PRINTID_TEXTID_ACCESSION, 41); */
1549 /*   AddLabel(seg2,r.left+xlen/2, height+25, title, SMALL_TEXT, 0, UPPER_CENTER, 0); */
1550 
1551   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1552   AddLine(seg2, r.left, height+10, r.left+xlen, height+10, FALSE,0);
1553 /*   AddLine(seg2, r.left, height-ylen, r.left+xlen, height-ylen, FALSE, -1); */
1554   sprintf(scale_buf, "%d", xstop);
1555   AddAttribute(seg2, COLOR_ATT, RED_COLOR, 0,0,0,0);
1556   AddLabel(seg2, r.left+xlen+10*scale, height+5, scale_buf, SMALL_TEXT, 0, MIDDLE_RIGHT, 0);
1557   
1558   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1559   if (!Decrement)
1560     {
1561       for (scale_pos = xstart, i=0; scale_pos <= xstop; scale_pos++, i++)
1562         {
1563           
1564           if (!(scale_pos % pos))
1565             {
1566               x = r.left + i;
1567               y = height+10;
1568               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1569               AddLine(seg2, x, y, x, y+bigtick, FALSE,-1);
1570               sprintf(scale_buf, "%d", scale_pos);
1571               AddAttribute(seg2, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
1572               AddLabel(seg2, x, y+15*scale, scale_buf, SMALL_TEXT, 0, UPPER_CENTER, 0);
1573               
1574             }
1575           else if (!(scale_pos % (pos/2)))
1576             {
1577               x = r.left + i;
1578               y = height+10;
1579               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1580               AddLine(seg2, x, y, x, y+midtick, FALSE,0);
1581               
1582             }
1583           else if (!(scale_pos % (pos/10)))
1584             {
1585               x = r.left + i;
1586               y = height+10;
1587               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1588               AddLine(seg2, x, y, x, y+smalltick, FALSE,0);
1589             }
1590         }
1591     }
1592   else
1593     {
1594       for (scale_pos = xstop, i=0, j=xstart; scale_pos <= xstart; scale_pos++, i++, j--)
1595         {
1596           
1597           if (!(scale_pos % pos))
1598                 {
1599                   x = r.left + i;
1600                   y = height+10;
1601                   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1602                   AddLine(seg2, x, y, x, y+bigtick, FALSE,0);
1603                   sprintf(scale_buf, "%d", j);
1604                   AddAttribute(seg2, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
1605                   AddLabel(seg2, x, y+15*scale, scale_buf, SMALL_TEXT, 0, UPPER_CENTER, 0);
1606                   
1607                 }
1608               else if (!(scale_pos % (pos/2)))
1609                 {
1610                   x = r.left + i;
1611                   y = height+10;
1612                   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1613                   AddLine(seg2, x, y, x, y+midtick, FALSE,0);
1614                   
1615                 }
1616               else if (!(scale_pos % (pos/10)))
1617                 {
1618                   x = r.left + i;
1619                   y = height+10;
1620                   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1621                   AddLine(seg2, x, y, x, y+smalltick, FALSE,0);
1622                 }
1623         }
1624     }
1625   
1626 }
1627 
1628 
1629 /*________________________________________(DOT_DrawYAxis)_____________
1630 
1631 
1632   Purpose : Draw y-axis function for viewer1, window2.
1633 
1634 ____________________________________________________________________*/
1635 void DOT_DrawYAxis(SegmenT seg2, RecT  r, Int4 height, Int4 ystart, Int4 ystop, Int4 scale, Int4 Fh, SeqIdPtr sip)
1636 {
1637   Int4         smalltick, midtick, bigtick;
1638   Int4         pos, ylen, x, y, scale_pos, i, j, Fh_2,Fh_4; 
1639   Char         scale_buf[15] = {""}, title[50]={""};    /*scale value*/
1640   Boolean      Decrement = FALSE;
1641 
1642 
1643   if (ystart>ystop)
1644     Decrement=TRUE;
1645 
1646   if (scale==0)
1647     scale=1;
1648 
1649   pos=100*scale;
1650   smalltick=5*scale;
1651   midtick=7*scale;
1652   bigtick=10*scale;
1653  
1654   Fh_2=Fh/2;
1655   Fh_4=Fh/4;
1656   
1657 
1658   ylen=ABS(ystop-ystart);
1659 
1660 /*   SeqIdWrite(sip, title ,PRINTID_TEXTID_ACCESSION, 41); */
1661 /*   AddLabel(seg2, height - ylen/2, r.left - 20, title, SMALL_TEXT, 0, MIDDLE_CENTER, 0); */
1662  
1663   AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1664   AddLine(seg2, r.left-10, height, r.left-10, height-ylen, FALSE, 0);
1665 
1666   sprintf(scale_buf, "%d", ystop);
1667   AddAttribute(seg2, COLOR_ATT, RED_COLOR, 0,0,0,0);
1668   AddLabel(seg2, r.left-10, height-ylen-10*scale, scale_buf, SMALL_TEXT, 0, MIDDLE_CENTER, 0);
1669 
1670   
1671   if (!Decrement)
1672     {
1673       for (scale_pos = ystart, i=0; scale_pos <= ystop; scale_pos++, i++)
1674         {
1675           if (!(scale_pos % pos))
1676             {
1677               x = r.left-10;
1678               y = height-i/* +VFrom */;
1679               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1680               AddLine(seg2, x, y, x-bigtick, y, FALSE, 0);
1681               
1682               sprintf(scale_buf, "%d", scale_pos);
1683               y = y-Fh_2;
1684               AddAttribute(seg2, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
1685               AddLabel(seg2, x-15*scale, y, scale_buf, SMALL_TEXT, 0, MIDDLE_LEFT, 0);
1686               
1687             }
1688           else if (!(scale_pos % (pos/2)))
1689             {
1690               x = r.left-10;
1691               y = height-i/* +VFrom */;
1692               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1693               AddLine(seg2, x, y, x-midtick, y, FALSE,0);
1694               
1695             }
1696           else if (!(scale_pos % (pos/10)))
1697             {
1698               x = r.left-10;
1699               y = height-i/* +VFrom */;
1700               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1701               AddLine(seg2, x, y, x-smalltick, y, FALSE,0);
1702             }
1703           
1704         }
1705     }
1706   else
1707     {
1708 
1709       for (scale_pos = ystop, i=0, j=ystart; scale_pos <= ystart; scale_pos++, i++, j--)
1710         {
1711           if (!(scale_pos % pos))
1712             {
1713               x = r.left-10;
1714               y = height-i/* +VFrom */;
1715               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1716               AddLine(seg2, x, y, x-bigtick, y, FALSE,0);
1717               
1718               sprintf(scale_buf, "%d", j);
1719               y = y-Fh_2;
1720               AddAttribute(seg2, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
1721               AddLabel(seg2, x-15*scale, y, scale_buf, SMALL_TEXT, 0, MIDDLE_LEFT, 0);
1722               
1723             }
1724           else if (!(scale_pos % (pos/2)))
1725             {
1726               x = r.left-10;
1727               y = height-i/* +VFrom */;
1728               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1729               AddLine(seg2, x, y, x-midtick, y, FALSE,0);
1730               
1731             }
1732           else if (!(scale_pos % (pos/10)))
1733             {
1734               x = r.left-10;
1735               y = height-i/* +VFrom */;
1736               AddAttribute(seg2, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
1737               AddLine(seg2, x, y, x-smalltick, y, FALSE,0);
1738             }     
1739         }
1740     }
1741 }
1742 
1743 
1744 /*________________________________________(DOT_DisplayDiags)_____________
1745 
1746 
1747   Purpose : Draw function for viewer1, window2.
1748 
1749 ____________________________________________________________________*/
1750 
1751 static Boolean DOT_SVDisplayDiags(DOTVibDataPtr vdp2, DOTSelDataPtr data)
1752 {
1753   RecT               rcP;
1754   DOTDiagPtr         PNTR hitlist;
1755   DOTVibDataPtr        vdp;
1756   VieweR             v;
1757   SegmenT            seg1, seg2, seg3, seg4;
1758   PrimitivE          prim;
1759   Int4               stop, cutoff=0, q_start, s_start, length;
1760   Int4               x, y, x2, y2;
1761   Int4               i, j;
1762   Int4               p_VFrom, p_HFrom;
1763   Int4               width, height;
1764   Int4               x_start, y_start;
1765   Int4               Right, Left, Top, Bottom;
1766   Int4               right_end, bottom_end;
1767   Int4               diag, aln_diag;
1768   Int4               q_left, q_right;
1769   Int4               s_top, s_bottom;
1770   Boolean            q_hitonplus=FALSE, s_hitonplus=FALSE;
1771   Boolean            lt_fixed=FALSE, rb_fixed=FALSE;
1772   Boolean            lb_fixed=FALSE, rt_fixed=FALSE;
1773   Boolean            query_on_minus = FALSE;
1774   DOTAlnPtr PNTR     alnL, aln;
1775 
1776   seg1=CreateSegment(vdp2->sv->pict1, 1, 0); /* diags */
1777   seg2=CreateSegment(vdp2->sv->pict1, 2, 0); /* axis */
1778   seg3=CreateSegment(vdp2->sv->pict1, 3, 0); /* diag coordinates */
1779   v=vdp2->sv->v1;
1780 
1781   GetPosition(v, &rcP); 
1782   InsetRect(&rcP, 4, 4);
1783   vdp = data->vdp;
1784   width = rcP.right-rcP.left;
1785   height = rcP.bottom-rcP.top-2*(vdp2->VERT_MARGIN*vdp2->sv->scaleValue);
1786   p_VFrom=vdp->sdp.VFrom;
1787   p_HFrom=vdp->sdp.HFrom;
1788   /* Rect Parameters */
1789   rcP.left+=2*(vdp2->HORZ_MARGIN*vdp2->sv->scaleValue);
1790   DOT_DrawXAxis(seg2, rcP, height, data->q_start, data->q_stop, vdp2->sv->scaleValue, (vdp2->mip?vdp2->mip->qbsp->id:vdp2->alp->sip));
1791   DOT_DrawYAxis(seg2, rcP, height, data->s_start, data->s_stop, vdp2->sv->scaleValue, vdp2->Fh, (vdp2->mip?vdp2->mip->sbsp->id:vdp2->alp->sip->next));
1792   AddAttribute(seg1, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1793 
1794 
1795   Left=MIN(data->q_start, data->q_stop);
1796   Right=MAX(data->q_start, data->q_stop);
1797   Top=MIN(data->s_start, data->s_stop);
1798   Bottom=MAX(data->s_start, data->s_stop);
1799   right_end=rcP.left+(Right-Left);
1800   bottom_end=height-(Bottom-Top);
1801 
1802   if (vdp2->mip && vdp2->showDotPlot){
1803     hitlist = vdp2->mip->hitlist;
1804     if (vdp2->mip->unique<=1)
1805       stop=vdp2->mip->index;
1806     else
1807       stop=DOT_LoopStop (vdp2);
1808     
1809     if (vdp2->strand1 == Seq_strand_minus)
1810       query_on_minus = TRUE;
1811     
1812     for (i = 0; i<stop ; i++)
1813       {  
1814          length = hitlist[i]->length-1;
1815          if (query_on_minus) 
1816            x_start = data->q_stop - hitlist[i]->q_start;
1817          else
1818            x_start =  hitlist[i]->q_start - data->q_start;
1819          y_start =   ABS(data->s_start-  hitlist[i]->s_start);
1820          if (query_on_minus){ 
1821            x = rcP.left + x_start; 
1822            x2 = x - length; 
1823          } 
1824          else { 
1825            x = rcP.left + x_start;
1826            x2 = x + length;
1827          } 
1828          
1829          /* in dot matrix subject is always on plus */
1830          y = height- y_start;
1831          y2 = y - length;
1832 
1833          prim = AddLine(seg1, x, y, x2, y2, FALSE,(Uint2)i + 1);
1834          if (prev_primID == (i + 1))
1835            HighlightPrimitive(v, seg1, prim, FRAME_PRIMITIVE);
1836        }
1837   }
1838 
1839   if (vdp2->alp && vdp2->showALIGN){
1840     seg4=seg1;
1841     AddAttribute(seg4, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
1842     
1843     alnL=vdp2->alp->Alnlist;
1844     stop = vdp2->alp->index;
1845     for (j = 0; j<stop; j++)
1846       {
1847         aln = alnL[j];
1848         q_start=aln->q_start-Left;
1849         s_start=aln->s_start-Top;
1850         length=aln->q_stop-aln->q_start;
1851 
1852         if (vdp2->strand1 == Seq_strand_minus){
1853           q_hitonplus=FALSE;
1854           x = rcP.left+q_start;
1855           x2 = x - length;
1856           q_left = x2;
1857           q_right = x;
1858         }
1859         else{
1860           q_hitonplus=TRUE;
1861           x = rcP.left + q_start;
1862           x2 = x + length;
1863           q_left = x;
1864           q_right = x2;
1865         }
1866 
1867         if (vdp2->strand2 == Seq_strand_minus){
1868           s_hitonplus=FALSE;
1869           y = height - s_start;
1870           y2 = y + length;
1871           s_top = y2;
1872           s_bottom = y;
1873         }
1874         else{
1875           s_hitonplus=TRUE;
1876           y = height - s_start;
1877           y2 = y - length;
1878           s_top = y;
1879           s_bottom = y2;
1880         }
1881         
1882         lt_fixed = rb_fixed = lb_fixed = rt_fixed = FALSE;
1883         if (q_left > right_end || q_right < rcP.left ||
1884             s_top < bottom_end || s_bottom > height)
1885           continue;
1886 
1887         if (q_hitonplus==s_hitonplus){
1888           diag=Bottom-Right;
1889           aln_diag=s_start-q_start;
1890           if (x<rcP.left){
1891             if (y>height){
1892               if (rcP.left-x < y-height/* aln_diag < diag */){
1893                 x=x+(y-height);
1894                 y=height;
1895               }
1896               else{
1897                 y=y-(rcP.left-x);
1898                 x=rcP.left;
1899               }
1900             }
1901             else{
1902               y=y-(rcP.left-x);
1903               x=rcP.left;
1904             }
1905             lt_fixed=TRUE;
1906           }
1907           if (x2>right_end){
1908             if (y2<bottom_end){
1909               if (x2-right_end < bottom_end-y2/* aln_diag > diag */){
1910                 x2=x2-(bottom_end-y2);
1911                 y2=bottom_end;
1912               }
1913               else{
1914                 y2=y2+(x2-right_end);
1915                 x2=right_end;
1916               }
1917             }
1918             else {
1919               y2=y2+(x2-right_end);
1920               x2=right_end;
1921             }
1922             rb_fixed=TRUE;
1923           }
1924           
1925             if (y>height && !lt_fixed){
1926               x=x+(y-height);
1927               y=height;
1928             }
1929             if (y2<bottom_end && !rb_fixed){
1930               x2=x2-(bottom_end-y2);
1931               y2=bottom_end;
1932             }
1933           }
1934           else{
1935             if (q_hitonplus){/* s must be minus */
1936 /*               if ( x > right_end || x2 < rcP.left || y2 <bottom_end || y>height) */
1937 /*                 continue; */
1938               diag=Bottom-Left;
1939               aln_diag=s_start-q_start;
1940               if (x<rcP.left){
1941                 if (y<bottom_end){
1942                   if (rcP.left-x < bottom_end-y/* aln_diag < diag */){
1943                     x=x+(bottom_end-y);
1944                     y=bottom_end;
1945                   }
1946                   else{
1947                     y=y+(rcP.left-x);
1948                     x=rcP.left;
1949                   }
1950                 }
1951                 else{
1952                   y=y+(rcP.left-x);
1953                   x=rcP.left;
1954                 }
1955                 lb_fixed=TRUE;
1956               }
1957               if (x2>right_end){
1958                 if (y2>height){
1959                   if (x2-right_end < y2-height/* aln_diag > diag */){
1960                     x2=x2-(y2-height);
1961                     y2=height;
1962                   }
1963                   else{
1964                     y2=y2-(x2-right_end);
1965                     x2=right_end;
1966                   }
1967                 }
1968                 else{
1969                   y2=y2-(x2-right_end);
1970                   x2=right_end;
1971                 }
1972                 rt_fixed=TRUE;
1973               }
1974               if (y<bottom_end && !lb_fixed){
1975                 x=x+(bottom_end-y);
1976                 y=bottom_end;
1977               }
1978               if (y2>height && !rt_fixed){
1979                 x2=x2-(y2-height);
1980                 y2=height;
1981               }
1982             }
1983             else if (s_hitonplus){/* q must be minus*/
1984 /*               if (y2 >height || y <bottom_end || x2<rcP.left || x>right_end) */
1985 /*                 continue; */
1986               diag=Bottom-Left;
1987               aln_diag=s_start-q_start;
1988               if (x> right_end){
1989                 if (y>height){
1990                   if (x-right_end < y-height/* aln_diag < diag */){
1991                     x=x-(y-height);
1992                     y=height;
1993                   }
1994                   else{
1995                     y=y-(x-right_end);
1996                     x=right_end;
1997                   }
1998                 }
1999                 else{
2000                   y=y-(x-right_end);
2001                   x=right_end;
2002                 }
2003                 lt_fixed=TRUE;
2004               }
2005               if(x2<rcP.left){
2006                 if (y2<bottom_end){
2007                   if (rcP.left-x2 < bottom_end-y2/* aln_diag > diag */){
2008                     x2=x2+(bottom_end-y2);
2009                     y2=bottom_end;
2010                   }
2011                   else{
2012                     y2=y2+(rcP.left-x2);
2013                     x2=rcP.left;
2014                   }
2015                 }
2016                 else {
2017                   y2=y2+(rcP.left-x2);
2018                   x2=rcP.left;
2019                 }
2020                 rb_fixed=TRUE;
2021               }
2022               if (y>height && !lt_fixed){
2023                 x=x-(y-height);
2024                 y=height;
2025               }
2026               if (y2<bottom_end && !rb_fixed){
2027                 x2=x2+(bottom_end-y2);
2028                 y2=bottom_end;
2029               }
2030               
2031             }
2032           }
2033           DOT_SetColor(seg4, aln->class, FALSE);
2034           prim=AddLine(seg4, x, y, x2, y2, FALSE, 0);
2035           SetPrimitiveIDs(prim,aln->entityID,aln->itemID, OBJ_SEQALIGN, aln->primID);
2036           if (prev_primID == aln->primID)
2037             HighlightPrimitive(v, seg1, prim, FRAME_PRIMITIVE);
2038       }
2039   }
2040   
2041   return TRUE;
2042 }
2043 
2044 /*________________________________________(DOT_WorldtoScreen)_____________
2045 
2046   Purpose : calculate sequence coordinates from screen coords.
2047 
2048 ____________________________________________________________________*/
2049 static Int4 DOT_WorldtoScreen(Int4 wPos, Int4 chw_2)
2050 {
2051   Int4  sPos;
2052 
2053   sPos=wPos*chw_2;
2054 
2055   return sPos;
2056 }
2057 
2058 /*________________________________________(DOT_DrawScale)_____________
2059 
2060   Purpose : Draw scale of aligned seqs, viewer2, window2.
2061 
2062 ____________________________________________________________________*/
2063 void DOT_DrawScale (SegmenT sbSeg, Uint1 strand1, Uint1 strand2, RecT  r, Int4 margin,Int4 res_cnt, Int4 bloc_cnt, Int4 Fh, Int4 q_pos, Int4 s_pos, Int4 chw_2, Int4 chw_4)
2064 {
2065   Char      Buf[15]={""};
2066   Int4      x, x2,y1, y2, y3, y4, y5, y6;
2067   Int4      pos, col;
2068 
2069 
2070   col =DOT_WorldtoScreen(res_cnt+bloc_cnt, chw_2); 
2071 
2072   x = r.left+margin+col-chw_4;
2073   y1=7*Fh;
2074   y2=y1-Fh/2;
2075   y3=y2-Fh/2;
2076   AddAttribute(sbSeg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2077   AddLine(sbSeg, x, y2, x, y3, FALSE, 0);
2078 
2079   pos=(strand1==Seq_strand_plus)?res_cnt+q_pos:ABS(q_pos-res_cnt); 
2080   sprintf(Buf,"%d",pos);
2081   x2=x-StringWidth(Buf)/2;
2082 
2083   AddAttribute(sbSeg, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
2084   AddLabel(sbSeg, x2,y1, Buf, SMALL_TEXT, 0, UPPER_RIGHT, 0);
2085 
2086   y4=2*Fh;
2087   y5=y4+Fh+Fh/2;
2088   y6=y5+Fh/2;
2089   AddAttribute(sbSeg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2090   AddLine(sbSeg, x, y6, x, y5, FALSE, 0);
2091 
2092   pos=(strand2==Seq_strand_plus)?res_cnt+s_pos:ABS(s_pos-res_cnt);
2093   sprintf(Buf,"%d",pos);
2094   x-=StringWidth(Buf)/2;
2095 
2096   AddAttribute(sbSeg, COLOR_ATT, BLUE_COLOR, 0,0,0,0);
2097   AddLabel(sbSeg, x2,y4, Buf, SMALL_TEXT, 0, UPPER_RIGHT, 0);
2098 
2099 }
2100 
2101 /*________________________________________(DOT_HlSeq)_____________
2102 
2103   Purpose : Draw line to show hit in alignment, viewer2, window2.
2104 
2105 ____________________________________________________________________*/
2106 static void DOT_HlSeq(SegmenT sbSeg, RecT  rcP, Int4 margin, Int4 wPos, Int4 bloc_pos, Int4 hit_start, Int4 hit_stop, Int4 Fh, Int4 chw_2)
2107 {
2108   Int4  xpos, len,  bloc_beg, begin, end;
2109   Int4  x1, x2, y1;
2110 
2111 
2112   bloc_beg = wPos-bloc_pos;
2113   begin = MAX(bloc_beg, hit_start);
2114   
2115   end = MIN(wPos,hit_stop);
2116   len = end - begin + 1;
2117   xpos = DOT_WorldtoScreen(begin, chw_2);
2118  
2119   x1= rcP.left + margin + xpos;
2120   x2= x1 + len * chw_2;
2121   y1 = 5 * Fh;
2122 
2123   AddAttribute(sbSeg, COLOR_ATT, RED_COLOR, 0,0,0,0);
2124   AddLine(sbSeg, x1, y1, x2, y1, FALSE,0); 
2125 
2126 }
2127 
2128 /*________________________________________(DOT_Highlight)_____________
2129 
2130   Purpose : Highlight matched residues, viewer2, window2.
2131 
2132 ____________________________________________________________________
2133 */
2134 static void DOT_Highlight(SegmenT sbSeg, RecT  rcP, Int4 margin, Int4 wPos, Int4 Fh, Int4 chw_2, Boolean match)
2135 {
2136   Int4  xpos, x1, x2, y1, y2;
2137 
2138   xpos=DOT_WorldtoScreen(wPos, chw_2);
2139 
2140   x1= rcP.left+margin+xpos;
2141   x2= x1+chw_2;
2142   y1 = 6*Fh;
2143   y2 = 4*Fh;
2144 
2145   if (match)
2146     AddAttribute(sbSeg, COLOR_ATT, YELLOW_COLOR,0,0,0,0);
2147   else
2148     AddAttribute(sbSeg, COLOR_ATT, CYAN_COLOR, 0,0,0,0);
2149   AddRectangle (sbSeg, x1, y1, x2, y2, 0, TRUE, 0);
2150 }
2151 
2152 
2153 /*________________________________________(DOT_UpdatePt)_____________
2154 
2155   Purpose : corrects clicked points for click/drag/release procs of window1.
2156 
2157 ____________________________________________________________________*/
2158 
2159 static void DOT_UpdatePt (void)
2160 {
2161   Int4    temp;
2162 
2163   if (curpnt.x < fstpnt.x)
2164     {
2165       temp = curpnt.x;
2166       curpnt.x = fstpnt.x;
2167       fstpnt.x = temp;
2168     }
2169 
2170   if (curpnt.y < fstpnt.y)
2171     {
2172       temp = curpnt.y;
2173       curpnt.y = fstpnt.y;
2174       fstpnt.y = temp;
2175     }
2176 
2177   return;
2178   
2179 }
2180 
2181 /*________________________________________(DOT_FillNewSeqBufs)_____________
2182 
2183   Purpose : Fill seq buffers for window2.
2184 
2185 ____________________________________________________________________*/
2186 static void DOT_FillNewSeqBufs (DOTVibDataPtr vdp, DOTVibDataPtr vdp2, Boolean is_zoom)
2187 {
2188   Int4      qlen, slen, i;
2189   Int4      q_start, s_start;
2190   Int4      q_left, q_right;
2191   Uint1Ptr  qseq=NULL, sseq=NULL, q=NULL, s=NULL, qBuf=NULL, sBuf=NULL;
2192   DOTSelDataPtr data=NULL;
2193   DOTMainDataPtr mip1=NULL, mip2=NULL;
2194   DOTAlignInfoPtr alp=NULL;
2195 
2196 
2197   data=(DOTSelDataPtr)vdp->data;
2198   mip1 =  vdp->mip;
2199   mip2 =  vdp2->mip;
2200 
2201   qlen=mip2->qlen;
2202   slen=mip2->slen;
2203   qseq = mip1->qseq;
2204   sseq = mip1->sseq;
2205   q_left=mip1->q_start;
2206   q_right = mip1->q_start + mip1->qlen - 1;
2207   s_start = mip1->s_start;
2208   if (is_zoom)
2209     {
2210       mip2->sseq=MemFree(mip2->sseq);
2211       mip2->qseq=MemFree(mip2->qseq);
2212     }
2213   
2214   
2215   /* get sequence position relative to the vdp sequence buffer */
2216   if (vdp2->strand1 == Seq_strand_minus)
2217     q_start = ABS(q_right - data->q_stop)/*  + q_left */;
2218   else
2219     q_start = ABS(q_left - data->q_start);
2220 
2221   q = qseq+ q_start;
2222   s = sseq+ ABS(s_start - data->s_start);
2223 
2224 
2225   if (!(qBuf = (Uint1Ptr) MemNew (sizeof(Uint1)*(qlen)))) return;
2226   if (!(sBuf = (Uint1Ptr) MemNew (sizeof(Uint1)*(slen)))) return;
2227   mip2->sseq=sBuf;
2228   mip2->qseq=qBuf;
2229   i=0;
2230   while(i< qlen)
2231     {        
2232       *qBuf=*q;
2233       i++;
2234       q++;
2235       qBuf++;
2236     }
2237   i=0;
2238   while(i< slen)
2239     {  
2240       *sBuf=*s;
2241       i++;
2242       s++;
2243       sBuf++;
2244     }
2245 }
2246 
2247 /*________________________________________(DOT_InitCInfo)_____________
2248 
2249   Purpose : Initialize vdp2 (DOTVibDataPtr for window2).
2250 
2251 ____________________________________________________________________*/
2252 
2253 static void DOT_InitCInfo(DOTVibDataPtr vdp, DOTVibDataPtr vdp2, DOTSelDataPtr data)
2254 {
2255   Char       colBuf[12]={""};
2256   DOTMainDataPtr mip1=NULL, mip2=NULL;
2257   BioseqPtr  qbsp, sbsp;
2258   
2259 
2260   /* set up second window parameters */  
2261   vdp2->sv=(DOTSeqViewrPtr)MemNew(sizeof(DOTSeqViewr));
2262   vdp2->Fnt = vdp->Fnt;
2263   vdp2->HORZ_MARGIN=vdp->HORZ_MARGIN;
2264   vdp2->VERT_MARGIN=vdp->VERT_MARGIN;
2265   vdp2->alp=vdp->alp;
2266 
2267   mip1 =  vdp->mip;
2268   if (mip1){
2269     qbsp = mip1->qbsp;
2270     sbsp = mip1->sbsp;
2271     mip2=(DOTMainDataPtr) MemNew (sizeof(DOTMainData));
2272     mip2=DOT_InitMainInfo (mip2, qbsp, sbsp, mip1->word_size, mip1->tree_limit, data->q_start, data->q_stop, data->s_start, data->s_stop);
2273     if (mip2->qslp)
2274       SeqLocFree(mip2->qslp);
2275     mip2->qslp = SeqLocIntNew(data->q_start, data->q_stop, vdp->strand1, qbsp->id);
2276     if (mip2->sslp)
2277       SeqLocFree(mip2->sslp);
2278     mip2->sslp = SeqLocIntNew(data->s_start, data->s_start, vdp->strand2, sbsp->id);
2279     mip2->qlen=data->qlen;
2280     mip2->slen=data->slen;
2281     vdp2->sdp.TrampPos=75;
2282     mip2->matrix = mip1->matrix;
2283     mip2->qstrand = mip1->qstrand;
2284     vdp2->mip= mip2;
2285   }
2286   else {
2287     vdp2->mip=NULL;
2288   }
2289   vdp2->xstart=data->q_start;
2290   vdp2->ystart=data->s_start;
2291   vdp2->xstop=data->q_stop;
2292   vdp2->ystop=data->s_stop;
2293   vdp2->xlen=data->qlen;
2294   vdp2->ylen=data->slen;
2295   vdp2->strand1=vdp->strand1;
2296   vdp2->strand2=vdp->strand2;
2297   vdp2->xname=vdp->xname;
2298   vdp2->yname=vdp->yname;
2299   /* sequence viewer initiatize */
2300 
2301   vdp2->sv->do_scale=TRUE;
2302   vdp2->sv->scaleValue=0;
2303   vdp2->sv->showLabels=FALSE;
2304   vdp2->sv->old_primID=-1;
2305 
2306 
2307   vdp2->curr_slen=data->slen;
2308   vdp2->curr_qlen=data->qlen;
2309   vdp2->data=data;
2310  
2311   /* hits info */
2312 
2313   vdp2->Fh=vdp->Fh;
2314   vdp2->charw=vdp->charw;
2315 }
2316 
2317 
2318 /*________________________________________(Init_bufs)_____________
2319 
2320   Purpose : Initialize sequence buffers to NULL.
2321 
2322 ____________________________________________________________________*/
2323 
2324 static void Init_bufs(CharPtr qBuf, CharPtr sBuf, Int4 size)
2325 {
2326   Int4   i;
2327 
2328   for (i = 0; i<size; i++)
2329     { 
2330       qBuf[i]= '\0'; 
2331       sBuf[i]= '\0'; 
2332     }
2333 }
2334 
2335 
2336 /*________________________________________(DOT_SVDisplaySequence)_____________
2337 
2338   Purpose : Draw function for viewer2 of second window.
2339 
2340 ____________________________________________________________________*/
2341 
2342 static void  DOT_SVDisplaySequence(DOTVibDataPtr vdp2, DOTAlnPtr salp)
2343 {
2344   RecT       rc;
2345   DOTVibDataPtr vdp;
2346   DOTSelDataPtr  data;
2347   DOTMainDataPtr mip1, mip2;
2348   SegmenT    pict2;
2349   SegmenT    nmSeg;
2350   SegmenT    clSeg;
2351   SegmenT    sbSeg;
2352   Boolean    match=FALSE;
2353   Uint1Ptr   q;
2354   Uint1Ptr   s;
2355   Uint1Ptr   end;
2356   Uint1Ptr   seq_aln1=NULL, seq_aln2=NULL;
2357   Int4       a,b,c, pos;
2358   Boolean    ambig=FALSE, is_na;
2359   Boolean    get_barposition=TRUE;
2360   Int4       i, k, spaces;
2361   Int4       prot_threshold=0, bloc_cntr;
2362   Int4       res_cnt, bloc_size;
2363   Int4       x, y, x2, y2;
2364   Int4       vis_2, buf_len;
2365   Int4       bufsize, sglen;
2366   Int4       xstart, xstop, ystart, ystop;
2367   Int4       hit_start, hit_stop, q_pos, s_pos;
2368   Int4       Fh, margin;
2369   Int4       xdiff_left,xdiff_right;
2370   Int4       ydiff_left,ydiff_right;
2371   Int4       width,height;
2372   Int4       chw_2, chw_4;
2373   CharPtr    qBuf;
2374   CharPtr    sBuf;
2375   CharPtr PNTR residue_names;
2376   Int4Ptr PNTR matrix;
2377   Uint1      strand1, strand2;
2378   Int4       num_cls, num_segs, seg_len;
2379   Int4       q_start, q_stop, s_start, s_stop;      
2380   Boolean    query_on_minus = FALSE;
2381   Uint2      highlight;
2382 
2383 
2384   data=(DOTSelDataPtr)vdp2->data;
2385   if (data==NULL) return;
2386   vdp=data->vdp;
2387   if (vdp==NULL)  return;
2388   mip1= vdp->mip;
2389   mip2= vdp2->mip;
2390   margin=MAX((StringWidth(vdp2->xname)), (StringWidth(vdp2->yname)))+10;
2391   GetPosition(vdp2->sv->v2, &rc);
2392   Fh=vdp2->Fh;
2393   vis_2=VIS_LEN/2;
2394 
2395   highlight = vdp2->sv->highlight;
2396 
2397   if (vdp2->strand1 == Seq_strand_minus)
2398     query_on_minus = TRUE;
2399 
2400   x = rc.left;
2401   y = 5*Fh; /* on top -cartesian */
2402   y2 = y -Fh;
2403   x2 = x + margin;
2404   chw_2=vdp2->charw/2;
2405   chw_4=vdp2->charw/4;
2406   pict2=vdp2->sv->pict2;
2407   width=ABS(data->q_stop-data->q_start);
2408   height=ABS(data->s_stop-data->s_start);
2409 
2410   /* in selected region coordinates */
2411   if (salp->show == dot_plot){
2412     matrix=mip1->matrix;
2413     is_na=mip1->is_na;
2414     if (mip1->is_na)
2415       residue_names=na_names;
2416     else
2417       residue_names=aa_names;
2418 
2419     strand1=mip1->qstrand;
2420     strand2=mip1->sstrand;
2421 
2422     if (query_on_minus) {
2423       q_start = data->q_stop - salp->q_start;
2424       q_stop = data->q_stop - salp->q_stop;
2425     }
2426     else {
2427       q_start = salp->q_start - data->q_start;
2428       q_stop = salp->q_stop - data->q_start;
2429     }
2430     s_start = ABS(data->s_start - salp->s_start);
2431     s_stop = ABS(data->s_start - salp->s_stop);
2432 
2433     xdiff_left = MIN(q_start, q_stop);
2434     xdiff_right = width - MAX(q_stop, q_start);
2435     ydiff_left = s_start;
2436     ydiff_right = height-s_stop;
2437     if (xdiff_left<ydiff_left)
2438       {
2439         xstart=0;
2440         ystart=ydiff_left-xdiff_left;
2441       }
2442     else
2443       {
2444         ystart=0;
2445         xstart=xdiff_left-ydiff_left;
2446       }
2447     
2448     if (xdiff_right<ydiff_right)
2449       {
2450         xstop= MAX(q_stop, q_start)+xdiff_right;
2451         ystop=s_stop+xdiff_right;
2452       }
2453     else
2454       {
2455         xstop=MAX(q_stop, q_start)+ydiff_right;
2456         ystop=s_stop+ydiff_right;
2457       }
2458     
2459     if ((xstop-xstart)!=(ystop-ystart))/* these should be equal*/
2460       return;
2461     
2462     data->xstart=xstart;
2463     data->xstop=xstop;
2464     data->ystart=ystart;
2465     data->ystop=ystop;
2466     
2467     buf_len=xstop-xstart+1;
2468     hit_start=q_start-xstart;
2469     hit_start+=hit_start/10;
2470     hit_stop=q_stop-xstart;
2471     if (query_on_minus) 
2472       q_pos = data->q_stop - xstart; 
2473     else
2474       q_pos = data->q_start + xstart;
2475     s_pos = data->s_start + ystart;
2476     s=vdp2->mip->qseq + xstart; 
2477     q=vdp2->mip->sseq + ystart; 
2478   }
2479   else if (salp->show == align_plot){
2480     matrix=vdp2->alp->matrix;
2481     is_na=vdp2->alp->is_na; 
2482     if (vdp2->alp->is_na)
2483       residue_names=na_names; 
2484     else 
2485       residue_names=aa_names; 
2486     strand1=AlnMgr2GetNthStrand(salp->sap, 1);
2487     strand2=AlnMgr2GetNthStrand(salp->sap, 2);
2488     q_pos=salp->q_start + 1;
2489     s_pos=salp->s_start + 1;
2490     hit_start=0;
2491     hit_stop=ABS(salp->q_stop-salp->q_start);
2492     seq_aln1=DOT_GetNthSeqFromAlign(salp->sap, 1);
2493     seq_aln2=DOT_GetNthSeqFromAlign(salp->sap, 2);
2494     if (seq_aln1==NULL || seq_aln2==NULL)
2495       return;
2496     q=seq_aln1;
2497     s=seq_aln2;
2498     buf_len=ABS(salp->q_stop-salp->q_start)+1;
2499   }
2500   end=s+buf_len-1;
2501   hit_stop+=hit_stop/10;
2502   seg_len=(rc.right-rc.left)/vdp2->charw;
2503   num_segs=buf_len/seg_len;
2504   if (seg_len%buf_len)
2505     num_segs++;
2506   if (num_segs==0)
2507       num_segs=1;
2508   num_cls=num_segs/5;
2509   if (5%num_segs)
2510     num_cls++;
2511   if (num_cls==0)
2512       num_cls=1;
2513   bufsize=seg_len+(seg_len/10)+2;
2514   qBuf=(CharPtr)MemNew(sizeof(Char)*bufsize);
2515   sBuf=(CharPtr)MemNew(sizeof(Char)*bufsize);
2516   i=0;
2517   a=0;b=0;c=0;
2518   spaces=0;res_cnt=0;bloc_cntr=0;bloc_size=1;
2519   k=1;
2520   for (a=0; a<num_cls; a++)
2521     {
2522       clSeg=CreateSegment(pict2,a+1,0);
2523       for(b=0; b<num_segs; b++)
2524         {
2525           sglen=seg_len;
2526           sbSeg=CreateSegment(clSeg,b+1,0);
2527           Init_bufs(qBuf,sBuf,seg_len);   
2528           for(c=0; c<sglen;c++)
2529             {
2530               if (!(i<buf_len))
2531                 {
2532                   a=num_cls;
2533                   b=num_segs;
2534                   sglen=c;
2535                   if (hit_start<=i && i<=(hit_stop+bloc_size))
2536                     {
2537                       DOT_HlSeq(sbSeg, rc, margin, i+1, bloc_size, hit_start, hit_stop, Fh,chw_2);
2538                     }
2539                   goto end;
2540                 }
2541 
2542               if (is_na)
2543                 {
2544                   if (*q > 3 || *s > 3)
2545                     ambig=TRUE;
2546                 }
2547               else
2548                 {
2549                   if (*q >24 || *s >24 || *q<1 || *s<1 )
2550                     ambig=TRUE;
2551                 }
2552 
2553               if (ambig)
2554                 {
2555                   if (s<end) /* not end */
2556                     {
2557                       qBuf[c]=*residue_names[(int)*q];
2558                       sBuf[c]=*residue_names[(int)*s];
2559                       ambig=FALSE;
2560                       goto skip; /* continue */
2561                     }
2562                   else
2563                     {
2564                       a=num_cls;
2565                       b=num_segs;
2566                       sglen=c;
2567                       if (hit_start<=i && i<=(hit_stop+bloc_size))
2568                         {
2569                           DOT_HlSeq(sbSeg, rc, margin, i+1, bloc_size, hit_start, hit_stop, Fh,chw_2);
2570                         }
2571                       goto end;
2572                     }
2573                 }
2574                         
2575               if (*s == *q)
2576                 match=TRUE;
2577             
2578             
2579               qBuf[c]=*residue_names[(int)*q];
2580               sBuf[c]=*residue_names[(int)*s];
2581               
2582               if (match == TRUE)
2583                 {
2584                   if (highlight == SHOW_MATCHES)
2585                     DOT_Highlight(sbSeg, rc, margin, i, Fh, chw_2, match);
2586                   match=FALSE;
2587                 }
2588               else if (highlight == SHOW_MISMATCHES)
2589                 DOT_Highlight(sbSeg, rc, margin, i, Fh, chw_2, match);
2590               
2591             skip:
2592 
2593               if (!(k % BLOCK_SIZE))
2594                 {
2595                   c++;
2596                   sglen++;
2597                   i++;
2598                   buf_len++;
2599                   bloc_size=0;
2600 
2601                   qBuf[c] = ' ';
2602                   sBuf[c] = ' ';
2603                   if(match)
2604                     spaces++;
2605                   
2606                   bloc_cntr++; 
2607                   res_cnt=i-bloc_cntr;
2608                   DOT_DrawScale(sbSeg, strand1, strand2, rc, margin, res_cnt, bloc_cntr, Fh, q_pos, s_pos, chw_2, chw_4);
2609                   if (hit_start<=i && i<(hit_stop+BLOCK_SIZE))
2610                     {
2611                       DOT_HlSeq(sbSeg, rc, margin, i, BLOCK_SIZE, hit_start, hit_stop, Fh, chw_2);
2612                       if (get_barposition)
2613                         {
2614                           pos=DOT_WorldtoScreen(i,chw_2);
2615                           vdp2->sv->barp=pos+rc.left+margin;
2616                           get_barposition=FALSE;
2617                         }
2618                     }
2619                 }
2620               
2621               i++;
2622               k++;
2623               q++;
2624               s++;
2625               bloc_size++;
2626               
2627             }
2628         end:
2629           
2630           /* attach buffer */
2631 
2632           pos=DOT_WorldtoScreen(i-sglen, chw_2);
2633           AddAttribute(sbSeg, COLOR_ATT, RED_COLOR, 0,0,0,0);
2634           AddLabel(sbSeg, x2+pos, y, qBuf , SMALL_TEXT, 0, UPPER_RIGHT, 0);
2635           AddAttribute(sbSeg, COLOR_ATT, BLACK_COLOR, 0,0,0,0);
2636           AddLabel(sbSeg, x2+pos, y2, sBuf , SMALL_TEXT, 0, UPPER_RIGHT, 0);
2637         }
2638     }
2639 
2640 /*write seq names */
2641 
2642   nmSeg=CreateSegment(pict2, num_cls+1, 0);
2643   AddAttribute(nmSeg, COLOR_ATT, MAGENTA_COLOR, 0,0,0,0);
2644   AddLabel(nmSeg, x, y, vdp2->xname, SMALL_TEXT, 0, UPPER_RIGHT, 0);
2645   AddLabel(nmSeg, x, y2, vdp2->yname, SMALL_TEXT, 0, UPPER_RIGHT, 0);
2646     
2647 
2648   MemFree(qBuf);
2649   MemFree(sBuf);
2650   if (seq_aln1)
2651     MemFree(seq_aln1);
2652   if (seq_aln2)
2653     MemFree(seq_aln2);
2654   return;
2655     
2656 }
2657 
2658 /*________________________________________(DOT_SVPopulateSequenceViewer)______
2659 
2660   Purpose : Calls draw function for viewer2 of second window.
2661 
2662 ____________________________________________________________________*/
2663 static Boolean DOT_SVPopulateSequenceViewer(DOTVibDataPtr vdp2)
2664 {
2665   RecT    rc;
2666   Char    infoBuf[255];
2667   DOTSelDataPtr data;
2668   DOTAlnPtr salp;
2669 
2670   data=(DOTSelDataPtr)vdp2->data;
2671   if (data==NULL) return FALSE;
2672 
2673   ResetViewer(vdp2->sv->v2);
2674   vdp2->sv->pict2=DeletePicture(vdp2->sv->pict2);
2675   Update();
2676 
2677   vdp2->sv->pict2=CreatePicture();
2678   GetPosition(vdp2->sv->v2, &rc);
2679 
2680   salp=vdp2->sv->salp;
2681   if (salp==NULL)
2682     {
2683       AddAttribute(vdp2->sv->pict2, COLOR_ATT, RED_COLOR, 0,0,0,0);
2684       AddLabel(vdp2->sv->pict2, rc.left, rc.bottom-rc.top, "- CLICK on a diagonal to view the aligned sequence -", SMALL_TEXT, 0, UPPER_RIGHT, 0);
2685        
2686       /*reset infopanel2 title*/
2687       SetTitle(vdp2->Infopanel, vdp2->iInfo);
2688       Disable(vdp2->Ggoto);
2689     }
2690   else
2691     {
2692       DOT_SVDisplaySequence(vdp2, salp);
2693 
2694       /*reset infopanel2 title*/
2695       sprintf(infoBuf, "Selected.. %s(x-axis) [%d..%d] vs. %s(y-axis) [%d..%d]", vdp2->xname, salp->q_start + 1, salp->q_stop + 1, vdp2->yname, salp->s_start + 1, salp->s_stop + 1);
2696 
2697       SetTitle(vdp2->Infopanel,infoBuf);
2698       Enable(vdp2->Ggoto);
2699     }
2700   
2701   
2702   AttachPicture(vdp2->sv->v2, vdp2->sv->pict2, vdp2->sv->barp, INT4_MIN, UPPER_CENTER, 1, 1, NULL);
2703   ArrowCursor();
2704   return TRUE;
2705  
2706 }
2707 
2708 
2709 /*________________________________________(DOT_SVFindHit)_____________
2710 
2711   Purpose : gets sequence coordinates of clicked diag (viewer2, window2)..
2712 
2713 ____________________________________________________________________*/
2714 DOTAlnPtr DOT_SVFindHit(DOTVibDataPtr vdp2, Int4 primID)
2715 {
2716   DOTAlnPtr  salp;
2717   Int4     index, s_start, q_start, len;
2718   Boolean  query_on_minus = FALSE;
2719 
2720 
2721   if (primID<1 || primID>vdp2->mip->index)
2722     return NULL;
2723 
2724   salp=(DOTAlnPtr)MemNew(sizeof(DOTAln));
2725   salp->show=dot_plot;
2726   index=primID-1;
2727   q_start=vdp2->mip->hitlist[index]->q_start;
2728   s_start=vdp2->mip->hitlist[index]->s_start;
2729   len=vdp2->mip->hitlist[index]->length-1;
2730   if (vdp2->strand1 == Seq_strand_minus)
2731     query_on_minus = TRUE;
2732 
2733   if (query_on_minus) { 
2734     salp->q_start = vdp2->xstart + ABS(vdp2->xstop - q_start);
2735     salp->q_stop = salp->q_start - len;
2736   }
2737   else {
2738     salp->q_start = q_start;
2739     salp->q_stop = q_start + len;
2740   }
2741 
2742   salp->s_start = s_start;
2743   salp->s_stop = s_start + len;
2744   salp->primID = (Uint2)primID;
2745   
2746   return salp;
2747 }
2748 
2749 
2750 
2751 /*________________________________________(DOT_SVGetDiag)_____________
2752 
2753   Purpose : Calls func to get sequence coordinates of clicked diag (viewer2, window2).
2754 
2755 ____________________________________________________________________*/
2756 
2757 static Boolean DOT_SVGetDiag (Uint2 segID, Uint2 primID, VoidPtr userdata)
2758 
2759 {
2760   DOTVibDataPtr  vdp2;
2761   DOTAlnPtr     salp;
2762 
2763   vdp2 = (DOTVibDataPtr) userdata;
2764   if (vdp2 == NULL || segID !=1) 
2765     return FALSE;
2766 
2767   salp=DOT_SVFindHit(vdp2, primID);
2768   userdata=(Pointer)salp;
2769   return TRUE;
2770 }
2771 /*________________________________________(DOT_DeSelectAll)_____________
2772 
2773    Purpose : Deselect all primitives.
2774 
2775 ____________________________________________________________________*/
2776 static Boolean DOT_DeSelectAll(SegmenT seg, PrimitivE prim, Uint2 segID,  Uint2 primID, Uint2 primCt, VoidPtr userdata)
2777 {
2778   Int1  highlight;
2779   VieweR  v;
2780 
2781   if (primID) {
2782     v = (VieweR) userdata;
2783     GetPrimDrawAttribute (prim, NULL, NULL, NULL, NULL, NULL, &highlight);
2784     if (highlight != PLAIN_PRIMITIVE) 
2785       HighlightPrimitive (v, seg, prim, PLAIN_PRIMITIVE);
2786   }
2787 
2788   return TRUE;
2789 }
2790 
2791 
2792 /*________________________________________(DOT_SVClickProc)_____________
2793 
2794    Purpose : Click proc for viewer1 of second window.
2795 
2796 ____________________________________________________________________*/
2797 static void DOT_SVClickProc(VieweR v, SegmenT seg, PoinT pt)
2798 {
2799   DOTVibDataPtr  vdp2;
2800   PrimitivE     prim=NULL;
2801   Uint2         primID = 0, entityID=0, itemtype=0;
2802   Uint4         itemID=0;
2803   Int1          highlight=0;
2804   Int2          handled=0;
2805   DOTAlnPtr     salp=NULL;
2806   SegmenT       seg1 = NULL;
2807 
2808   vdp2=(DOTVibDataPtr)GetObjectExtra((WindoW)ParentWindow(v));
2809   if(!vdp2) return;
2810   seg1 = FindSegPrim(v, pt, NULL, NULL, &prim);
2811   if (seg1 != NULL)
2812     {
2813       GetPrimitiveIDs(prim, &entityID, &itemID, &itemtype, &primID);
2814     if (primID != 0)
2815       {
2816         GetPrimDrawAttribute (prim, NULL, NULL, NULL, NULL, NULL, &highlight);
2817         if (highlight == PLAIN_PRIMITIVE) {
2818           ExploreSegment (seg1, (Pointer)v, DOT_DeSelectAll);
2819           HighlightPrimitive (v, seg, prim, FRAME_PRIMITIVE);
2820 
2821           if (entityID && itemID && itemtype) { /* alignment */
2822             salp=DOT_FindAlignment(vdp2, primID);
2823           }
2824           else { /* dot matrix hit */
2825             salp = DOT_SVFindHit(vdp2, primID);
2826           }
2827           prev_primID = primID;
2828         }
2829         else {
2830           ExploreSegment (seg1, (Pointer)v, DOT_DeSelectAll);
2831           salp = NULL;
2832           prev_primID = 0;
2833         }
2834       }
2835   }
2836   else {
2837     ExploreSegment (seg, (Pointer)v, DOT_DeSelectAll);
2838     salp = NULL;
2839     prev_primID = 0;
2840   }
2841   if (vdp2->sv->salp) 
2842     MemFree(vdp2->sv->salp);
2843   vdp2->sv->salp=salp;
2844   DOT_SVPopulateSequenceViewer (vdp2);
2845 }
2846 
2847   
2848 
2849 /*________________________________________(DOT_SVPopulateDiagViewer)_____________
2850 
2851   Purpose : Calls draw function for diags.
2852 
2853 ____________________________________________________________________*/
2854 static Boolean DOT_SVPopulateDiagViewer(DOTVibDataPtr vdp2)
2855 {
2856   Int4       index;
2857   Char       str[16];
2858   DOTSelDataPtr  data;
2859   
2860   
2861   data=(DOTSelDataPtr)vdp2->data;
2862   
2863   ResetViewer(vdp2->sv->v1);
2864   vdp2->sv->pict1=DeletePicture(vdp2->sv->pict1);
2865   Update();
2866 
2867   vdp2->sv->pict1=CreatePicture();
2868    
2869   if (DOT_SVDisplayDiags(vdp2, data)==FALSE)
2870     return FALSE;
2871   
2872   if (vdp2->sv->do_scale) 
2873     {
2874       for (index=1; index<MAXZOOMSCALEVAL; index++) 
2875         {
2876           sprintf (str, "%d", (long) (zoomScaleVal [index]));
2877           PopupItem (vdp2->sv->scale, str);
2878         }
2879       SetValue (vdp2->sv->scale, vdp2->sv->scaleIndex);
2880       vdp2->sv->do_scale = FALSE;
2881 
2882     }
2883 
2884   SafeShow(vdp2->sv->scale);
2885 
2886  
2887   AttachPicture(vdp2->sv->v1, vdp2->sv->pict1, INT4_MIN, INT4_MAX, LOWER_RIGHT,  vdp2->sv->scaleValue , vdp2->sv->scaleValue , NULL);
2888   if (vdp2->showDotPlot && vdp2->showALIGN){/* not clickable*/
2889     ArrowCursor();
2890     return TRUE;
2891   }
2892   SetViewerProcs (vdp2->sv->v1, DOT_SVClickProc, NULL, NULL, NULL);
2893   ArrowCursor();
2894   return TRUE;
2895   
2896 }
2897 
2898 
2899 /*____________________________________________(DOT_ChangeSequenceWindowCutoff)______
2900 
2901   Purpose : Change threshold for diag using threshold ramp.
2902 
2903 ____________________________________________________________________*/
2904 static void DOT_ChangeSequenceViewerCutoff (BaR b, GraphiC g, Int2 new, Int2 old) 
2905 {
2906   DOTVibDataPtr vdp2;
2907   WindoW     w;
2908 
2909   w=(WindoW)ParentWindow(b);
2910   vdp2 = (DOTVibDataPtr) GetObjectExtra (w);
2911 
2912   vdp2->sdp.TrampPos = new+20;
2913   DOT_SVPopulateDiagViewer(vdp2);
2914 
2915 }
2916 
2917 /*________________________________________(DOT_SVChangeScale)_____________
2918 
2919   Purpose : Change scale.
2920 
2921 ____________________________________________________________________*/
2922 static void DOT_SVChangeScale (PopuP p)
2923 
2924 {
2925   DOTVibDataPtr vdp2;
2926   Int4       index;
2927 
2928   vdp2 = (DOTVibDataPtr) GetObjectExtra (p);
2929   if (vdp2 != NULL) 
2930     {
2931       index = GetValue (vdp2->sv->scale);
2932       if (index <= MAXZOOMSCALEVAL && index > 0) 
2933         {
2934           vdp2->sv->scaleValue = zoomScaleVal [index];
2935         } 
2936       else 
2937         {
2938           vdp2->sv->scaleValue = 1;
2939         }
2940 
2941 /*       AttachPicture(vdp2->sv->v1, vdp2->sv->pict1, INT4_MIN, INT4_MAX, LOWER_RIGHT,  vdp2->sv->scaleValue , vdp2->sv->scaleValue , NULL); */
2942 /*       SetViewerProcs (vdp2->sv->v1, DOT_SVClickProc, NULL, NULL, NULL); */
2943       DOT_SVPopulateDiagViewer (vdp2);
2944     }
2945 }
2946 /*________________________________________(DOT_SVChangeLabels)_____________
2947 
2948   Purpose : Show or Hide coordinate labels for diags.
2949 
2950 ____________________________________________________________________*/
2951 static void DOT_SVChangeLabels (GrouP g)
2952 
2953 {
2954   DOTVibDataPtr  vdp2;
2955 
2956   vdp2 = (DOTVibDataPtr) GetObjectExtra (g);
2957   if (vdp2 != NULL) 
2958   {
2959       vdp2->sv->showLabels=(Boolean)(GetValue(vdp2->sv->Labels)==1);
2960       DOT_SVPopulateDiagViewer (vdp2);
2961   }
2962 }
2963 
2964 /*________________________________________(DOT_SVCalculateScaling)_____________
2965 
2966   Purpose : Estimates size of picture.
2967 
2968 ____________________________________________________________________*/
2969 static void DOT_SVCalculateScaling (DOTVibDataPtr vdp2)
2970 
2971 {
2972   RecT   r;
2973   Int4   index, r_hgt, r_wdt;
2974   double w_hgt, w_wdt, scale;
2975   double f1, f2;
2976 
2977   w_hgt=vdp2->ylen+(vdp2->ylen*0.15);
2978   w_wdt=vdp2->xlen+(vdp2->xlen*0.15);
2979 
2980   GetPosition(vdp2->sv->v1, &r);
2981   r_hgt=r.bottom-r.top;
2982   r_wdt=r.right-r.left;
2983 
2984   f1=(float)w_hgt/r_hgt;
2985   f2=(float)w_wdt/r_wdt;
2986 
2987   scale=MAX(ceil(f1), ceil(f2));
2988 
2989   for (index=1; index<MAXZOOMSCALEVAL; index++) 
2990     {
2991       if (zoomScaleVal [index]>= scale)
2992         {
2993           vdp2->sv->scaleValue=zoomScaleVal[index];
2994           vdp2->sv->scaleIndex=index;
2995           return;
2996         }
2997     }
2998 
2999   vdp2->sv->scaleValue=zoomScaleVal[MAXZOOMSCALEVAL-1];
3000   vdp2->sv->scaleIndex=MAXZOOMSCALEVAL-1;
3001 
3002 }
3003 
3004 /*________________________________________(DOT_ResizeFeatWindow)_____________
3005 
3006   Purpose : Resize function for window2.
3007 
3008 ____________________________________________________________________*/
3009 
3010 static void DOT_ResizeFeatWindow(WindoW w)
3011 {
3012   RecT     rcDlg,rcQry,rcSub, rcVsb,rcHsb, rcQi, rcSi;
3013   Int2     height,width,vsbWidth,in,gap,hsbHeight,QueryHeight,SubjectHeight, halfw;
3014   BaR      vsb,hsb;
3015   DOTFeatListPtr flp;
3016   WindoW   temport;
3017 
3018 
3019   flp=(DOTFeatListPtr)GetObjectExtra(w);
3020   temport=SavePort(w);
3021 
3022   ObjectRect(w,&rcDlg);
3023   width= rcDlg.right-rcDlg.left;
3024   halfw=width/2;
3025   height= rcDlg.bottom-rcDlg.top;
3026   
3027   SafeHide(flp->Query);
3028   SafeHide(flp->Subject);
3029   SafeHide(flp->QInfo);
3030   SafeHide(flp->SInfo);
3031   Update();
3032   
3033   vsb = GetSlateVScrollBar ((SlatE) flp->Query);
3034   hsb = GetSlateHScrollBar ((SlatE) flp->Subject);
3035   
3036   GetPosition(flp->Query,&rcQry);
3037   GetPosition(flp->Subject,&rcSub);
3038   GetPosition(flp->QInfo, &rcQi);
3039   GetPosition(flp->SInfo, &rcSi);
3040   GetPosition(vsb,&rcVsb);
3041   GetPosition(hsb,&rcHsb);
3042 
3043   in=2;
3044   gap=10;
3045   vsbWidth=rcVsb.right-rcVsb.left;
3046   hsbHeight=rcHsb.bottom-rcHsb.top;
3047   QueryHeight=rcQry.bottom-rcQry.top;
3048   SubjectHeight=rcSub.bottom-rcSub.top;
3049   
3050   /*new sizes for the viewers*/ 
3051   rcSub.right=width-in-vsbWidth;
3052   rcSub.bottom=height-in-hsbHeight;
3053   rcSub.left=halfw+in;
3054   rcSi.left=rcSub.left;
3055   rcQry.right=halfw-in-vsbWidth;
3056   rcQry.bottom=height-in-hsbHeight;
3057 
3058  
3059   
3060   /*set the new sizes*/
3061   SetPosition(flp->Query,&rcQry);
3062   AdjustPrnt (flp->Query, &rcQry, FALSE);
3063   SetPosition(flp->Subject,&rcSub);
3064   AdjustPrnt (flp->Subject, &rcSub, FALSE);
3065   SetPosition(flp->SInfo,&rcSi);
3066   AdjustPrnt (flp->SInfo, &rcSi, FALSE);
3067 
3068   AttachPicture (flp->Query,flp->segQuery, INT4_MIN, flp->vert_Qpos, UPPER_LEFT,1 , 1, NULL); 
3069   SetViewerProcs (flp->Query, DOT_QViewerClickProc, NULL, NULL, NULL);
3070 
3071   AttachPicture (flp->Subject,flp->segSubject, INT4_MIN, flp->vert_Spos, UPPER_LEFT,1 , 1, NULL);  
3072   SetViewerProcs (flp->Subject, DOT_SViewerClickProc, NULL, NULL, NULL);
3073 
3074   SafeShow(flp->QInfo);
3075   SafeShow(flp->SInfo);
3076   SafeShow(flp->Query);
3077   SafeShow(flp->Subject);
3078   RestorePort(temport);
3079   Update();
3080 }
3081 
3082 /*________________________________________(DOT_ResizeSequenceWindow)_____________
3083 
3084   Purpose : Resize function for window2.
3085 
3086 ____________________________________________________________________*/
3087 
3088 static void DOT_ResizeSequenceWindow(WindoW w)
3089 {
3090   Int4     lmargin;
3091   RecT     rcDlg,rcV1,rcV2, rcVsb,rcHsb, rcGoto;
3092   Int2     height,width,gap,vsbWidth,in,hsbHeight,V1Height,V2Height, goHeight;
3093   BaR      vsb,hsb;
3094   DOTVibDataPtr vdp2;
3095   Boolean  is_visible1, is_visible2;
3096   WindoW   temport;
3097 
3098 
3099   vdp2=(DOTVibDataPtr)GetObjectExtra(w);
3100   temport=SavePort(w);
3101   ObjectRect(w,&rcDlg);
3102   width= rcDlg.right-rcDlg.left;
3103   height= rcDlg.bottom-rcDlg.top;
3104   
3105   SafeHide(vdp2->sv->v1);
3106   SafeHide(vdp2->sv->v2);
3107   SafeHide(vdp2->Infopanel);
3108   SafeHide(vdp2->Ggoto);
3109   Update();
3110   
3111   vsb = GetSlateVScrollBar ((SlatE) vdp2->sv->v1);
3112   hsb = GetSlateHScrollBar ((SlatE) vdp2->sv->v1);
3113   
3114   GetPosition(vdp2->sv->v1,&rcV1);
3115   GetPosition(vdp2->sv->v2,&rcV2);
3116   GetPosition(vsb,&rcVsb);
3117   GetPosition(hsb,&rcHsb);
3118   GetPosition(vdp2->Ggoto, &rcGoto);
3119 
3120 
3121   gap=2;
3122   in=vdp2->Fh;
3123   lmargin=10;
3124   vsbWidth=rcVsb.right-rcVsb.left;
3125   hsbHeight=rcHsb.bottom-rcHsb.top;
3126   V1Height=rcV1.bottom-rcV1.top;
3127   V2Height=9*vdp2->Fh;
3128   goHeight= rcGoto.bottom-rcGoto.top;
3129 
3130   /*new sizes for the viewers*/ 
3131   rcV1.left=lmargin;
3132   rcV1.right=width-gap-vsbWidth-rcV1.left;
3133   rcV2.bottom=height-gap-in-hsbHeight;
3134   rcV2.top=rcV2.bottom-V2Height;
3135   rcGoto.bottom=rcV2.top-gap;
3136   rcGoto.top=rcGoto.bottom-goHeight;
3137   rcV1.bottom=rcGoto.top-gap-hsbHeight;
3138   rcV2.left=lmargin;
3139   rcV2.right=width-gap-vsbWidth-rcV2.left;
3140   
3141   /*set the new sizes*/
3142   SetPosition(vdp2->sv->v1,&rcV1);
3143   AdjustPrnt (vdp2->sv->v1, &rcV1, FALSE);
3144   
3145   SetPosition(vdp2->sv->v2,&rcV2);
3146   AdjustPrnt (vdp2->sv->v2, &rcV2, FALSE);
3147 
3148   SetPosition(vdp2->Ggoto, &rcGoto);
3149   AdjustPrnt(vdp2->Ggoto, &rcGoto, FALSE);
3150   
3151   if ((rcV1.left<rcV1.right)&&(rcV1.top<rcV1.bottom))
3152     is_visible1=TRUE;
3153   if ((rcV2.left<rcV2.right)&&(rcV2.top<rcV2.bottom))
3154     is_visible2=TRUE;
3155 
3156   /*update viewers*/
3157   if (Visible (vdp2->sv->v1) && AllParentsVisible (vdp2->sv->v1))
3158     ViewerWasResized(vdp2->sv->v1);
3159   if (Visible (vdp2->sv->v2) && AllParentsVisible (vdp2->sv->v2))
3160     ViewerWasResized(vdp2->sv->v2);
3161   
3162   if (vdp2->sv->do_scale!=TRUE) /* window resized */
3163     {
3164       DOT_SVPopulateDiagViewer(vdp2);
3165       DOT_SVPopulateSequenceViewer(vdp2);
3166     }
3167                        
3168   SafeShow(vdp2->sv->v1);
3169   SafeShow(vdp2->sv->v2);
3170   SafeShow(vdp2->Infopanel);
3171   SafeShow(vdp2->Ggoto);
3172   ArrowCursor();
3173   RestorePort(temport);
3174   Update();
3175 }
3176 
3177  static Boolean DOT_DeleteCursorPrim (SegmenT seg, PrimitivE prim, Uint2 segID,
3178                            Uint2 primID, Uint2 primCt, VoidPtr userdata)
3179 {
3180   DeletePrim(seg,prim);
3181   return TRUE;
3182 }
3183 
3184 
3185 static Int4 DOT_PointCursorOnFeature(SegmenT seg, DOTSelFeatPtr feat_list, Int2 fontHt, Boolean found)
3186 {
3187   Int4  yBase, cursorHt;
3188   Boolean is_first =TRUE;
3189   Int4  vertbar_pos;
3190 
3191   cursorHt=fontHt/4;
3192 
3193   if (!found)
3194     {
3195       AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
3196       yBase = (-1)*(feat_list->feat_num*(fontHt)-cursorHt);
3197       vertbar_pos=yBase+3*fontHt;
3198       AddRectangle(seg, 0,yBase, 2,yBase-2*cursorHt,RIGHT_ARROW,TRUE,0);
3199     }
3200   else
3201     {
3202       AddAttribute(seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);      
3203       while (feat_list)
3204         {
3205           yBase = (-1)*((feat_list->feat_num-1)*fontHt+cursorHt);
3206           if (is_first)
3207             {
3208               vertbar_pos=yBase+3*fontHt;
3209               is_first=FALSE;
3210             }
3211           AddRectangle(seg, 0,yBase, 2,yBase-2*cursorHt,RIGHT_ARROW,TRUE,0);
3212           feat_list=feat_list->next;
3213         }
3214     }
3215   return (vertbar_pos);
3216 }
3217 
3218 static DOTFeatPtr   DOT_FindNextDfp(DOTFeatIndexPtr fdindex, DOTFeatPtr dfp, Boolean use_first)
3219 {
3220   if (!use_first)
3221     dfp=dfp->next;
3222   while (dfp != NULL)
3223     {
3224       if (fdindex[dfp->type].show)
3225         return dfp;
3226       dfp=dfp->next;
3227     }
3228   return NULL;
3229 }
3230 
3231 
3232 static DOTSelFeatPtr DOT_FindFeatureInViewer(DOTFeatIndexPtr fdindex, DOTRowPtr drp, Int4 cursor_pos)
3233 {
3234   DOTFeatPtr dfp_head;
3235   DOTSelFeatPtr feat_list=NULL;
3236   Int4       i;
3237 
3238   /* fix this so that it also works for minus strand */
3239   i=1;
3240   dfp_head = DOT_FindNextDfp(fdindex, drp->dfp, TRUE);
3241   while (dfp_head != NULL)
3242     {
3243       if (dfp_head->left<= cursor_pos && dfp_head->right >= cursor_pos)
3244         {
3245           if (!feat_list)
3246             {
3247               feat_list=(DOTSelFeatPtr)MemNew(sizeof(DOTSelFeat));
3248             }
3249           else
3250             {
3251               feat_list->next=(DOTSelFeatPtr)MemNew(sizeof(DOTSelFeat));
3252               feat_list=feat_list->next;
3253             }
3254           feat_list->feat_num = i;
3255         }
3256       if (dfp_head->right > cursor_pos)
3257         {
3258           if (feat_list) 
3259             return feat_list;
3260           else 
3261             return NULL;
3262         }
3263       i++;
3264       dfp_head=DOT_FindNextDfp(fdindex, dfp_head, FALSE);
3265     }
3266   return NULL;
3267 }
3268 
3269 
3270 
3271 static DOTSelFeatPtr DOT_FindBetweenFeats(DOTFeatIndexPtr fdindex, DOTRowPtr drp, Int4 cursor_pos)
3272 {
3273   DOTFeatPtr dfp1;
3274   DOTSelFeatPtr feat_list=NULL;
3275   Int4       i;
3276 
3277   /* fix this so that it also works for minus strand */
3278   i=1;
3279   dfp1 = DOT_FindNextDfp(fdindex, drp->dfp, TRUE);
3280   if (!dfp1) goto end;
3281 /*   dfp2 = DOT_FindNextDfp(fdindex, dfp1, FALSE); */
3282 /*   if (!dfp2) goto end; */
3283 
3284   while (dfp1 != NULL /* && dfp2 != NULL */)
3285     {
3286       if (dfp1->left > cursor_pos)
3287         {
3288           if (!feat_list)
3289             {
3290               feat_list=(DOTSelFeatPtr)MemNew(sizeof(DOTSelFeat));
3291               feat_list->feat_num = i-1;
3292               return (feat_list);
3293             }
3294         }
3295     
3296       i++;
3297       dfp1=DOT_FindNextDfp(fdindex, dfp1, FALSE);
3298 /*       dfp2=DOT_FindNextDfp(fdindex, dfp1, FALSE); */
3299     }
3300 
3301  end:
3302   feat_list=(DOTSelFeatPtr)MemNew(sizeof(DOTSelFeat));
3303   feat_list->next=NULL;
3304   feat_list->feat_num = MAX(i-1, 1);
3305   return (feat_list);
3306 
3307 }
3308 /*******************************************************************************
3309 
3310   Function : DOT_AddFeatureToSegment()
3311   
3312   Purpose : analyse one feature and add it to the Feature Viewer
3313 
3314 *******************************************************************************/
3315 static void DOT_AddFeatureToSegment(SeqMgrFeatContextPtr context,
3316                         DOTPopFeatPtr pfp) 
3317 {
3318 PrimitivE  prim;
3319 Int4       yBase, xMargin;
3320 Char     str[50]; 
3321 
3322 
3323  sprintf(str, "%s (%d - %d)", pfp->dfp_cur->label, pfp->dfp_cur->left, pfp->dfp_cur->right); 
3324  AddAttribute(pfp->TopParentSeg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
3325  yBase = (-1)*pfp->nfeats*pfp->fontHeight;
3326  xMargin=5;
3327 
3328  if (context->numivals==1){
3329 
3330  prim = AddLabel(pfp->TopParentSeg, xMargin, yBase, str, SMALL_TEXT, 0, UPPER_RIGHT, 0);
3331  SetPrimitiveIDs(prim,context->entityID,context->itemID,OBJ_SEQFEAT, 0);
3332         }
3333  /*
3334         else{
3335                 DOT_AddSegmentedFeature(pfp->TopParentSeg,context->numivals,context->ivals, context->strand,context->entityID,context->itemID,yBase);
3336         }
3337  */
3338 }
3339 
3340 /*******************************************************************************
3341 
3342   Function : DOT_AddFeaturesToViewer()
3343   
3344   Purpose : callback called by SeqMgr (see also DOT_PopFeatureViewers(), below)
3345 
3346 *******************************************************************************/
3347 static Boolean LIBCALLBACK DOT_AddFeaturesToViewer(SeqFeatPtr sfp, 
3348                         SeqMgrFeatContextPtr context)
3349 {
3350 DOTFeatPtr           dfp_new=NULL;
3351 DOTRowPtr            drp=NULL;
3352 DOTFeatIndexPtr      fdindex=NULL; 
3353 DOTPopFeatPtr         pfp=NULL;
3354 
3355  
3356         pfp = (DOTPopFeatPtr) context->userdata;
3357 
3358         if (pfp==NULL){
3359                 return(FALSE);
3360         }
3361 
3362 
3363    drp=pfp->drp;
3364    
3365    if (pfp->dfp_cur == NULL) 
3366      {
3367        drp->dfp=(DOTFeatPtr)MemNew(sizeof(DOTFeat));
3368        pfp->dfp_cur=drp->dfp;
3369        dfp_new = drp->dfp;
3370      }
3371    else
3372      {
3373        if(!(pfp->dfp_cur->next=(DOTFeatPtr)MemNew(sizeof(DOTFeat)))) return(FALSE);
3374        pfp->dfp_cur=pfp->dfp_cur->next;
3375        dfp_new = pfp->dfp_cur;
3376      }
3377 
3378    if (!dfp_new) return(FALSE);
3379 
3380        
3381    if (context->strand>Seq_strand_minus ||
3382        context->strand==Seq_strand_unknown) 
3383      {
3384        pfp->dfp_cur->strand=Seq_strand_plus;
3385      }
3386 
3387        dfp_new->label=(CharPtr)FeatDefTypeLabel(sfp);
3388        dfp_new->left=context->left;
3389        dfp_new->right=context->right;
3390        dfp_new->type=context->featdeftype;
3391   
3392        /*add a feature to the viewer*/
3393 /*      DOT_AddFeatureToSegment(context,pfp);  */
3394        
3395 
3396        pfp->nfeats++;
3397        fdindex = pfp->featindex;
3398        
3399        if (!fdindex[context->featdeftype].present)
3400          {
3401            fdindex[context->featdeftype].present=TRUE;
3402            fdindex[context->featdeftype].show=TRUE;
3403            fdindex[context->featdeftype].label=dfp_new->label;
3404   
3405          }
3406        
3407         return(TRUE);
3408 }
3409 
3410 
3411 static Boolean DOT_DeletePrims(SegmenT seg, PrimitivE prim, Uint2 segID,
3412                            Uint2 primID, Uint2 primCt, VoidPtr userdata)
3413 {
3414   
3415   DeletePrim(seg, prim);
3416   return TRUE;
3417    
3418 }
3419 
3420 static void DOT_PlaceCursors(VieweR viewer, SegmenT seg, SegmenT segCursor, DOTFeatIndexPtr fdindex, DOTRowPtr drp, Int4 seqpos, Int2 fontHt, Int4Ptr ypos, Boolean from_click, Int4 fpos)
3421 {
3422   Boolean found;
3423   DOTSelFeatPtr foundfeats;
3424   Int4    Y_pos;
3425   WindoW  temport;
3426   RecT    rcP;
3427 
3428   if (!from_click)
3429     {
3430       foundfeats=DOT_FindFeatureInViewer(fdindex, drp, seqpos); 
3431       if (!foundfeats)
3432         {
3433           foundfeats=DOT_FindBetweenFeats(fdindex, drp, seqpos);
3434           found=FALSE;
3435         }
3436       else
3437         found=TRUE;
3438     }
3439   else
3440     {
3441       foundfeats=(DOTSelFeatPtr)MemNew(sizeof(DOTSelFeat));
3442       foundfeats->feat_num=fpos;
3443       foundfeats->next=NULL;
3444       found=TRUE;
3445     }
3446   ExploreSegment (segCursor, NULL, DOT_DeleteCursorPrim);
3447   Y_pos=DOT_PointCursorOnFeature(segCursor, foundfeats, fontHt, found);
3448   *ypos=Y_pos;
3449 
3450 /*   if (from_main_viewer)  */
3451 /*     { */
3452 /*       bar=GetSlateHScrollBar((SlatE) viewer); */
3453 /*       Y_pos=GetBarValue(bar); */
3454 /*     } */
3455 /*   else */
3456 /*     SetBarValue(GetSlateHScrollBar((SlatE) viewer), Y_pos); */
3457 
3458   MemFree(foundfeats); /* fix this !!*/
3459   if (from_click)
3460     {
3461       temport = SavePort(ParentWindow(viewer));
3462       Select(viewer);
3463       GetPosition(viewer, &rcP);
3464       InsetRect(&rcP, -1, -1);
3465       InvalRect(&rcP);
3466       RestorePort(temport);
3467       Update();
3468     }
3469   else
3470     {
3471       AttachPicture (viewer, seg, INT4_MIN, Y_pos, UPPER_LEFT,1 , 1, NULL); 
3472     }
3473     
3474   
3475 }
3476 
3477 
3478 static void DOT_QViewerClickProc(VieweR v, SegmenT seg, PoinT pt)
3479 {
3480   DOTFeatListPtr flp;
3481   DOTFeatPtr     dfp;
3482   DOTSelDataPtr  data;
3483   Int4           i, xmidPt, comp;
3484   Uint2          segID, primID, primCT;
3485   PrimitivE      prim;
3486   RecT           rc;
3487   Char           infoBuf[255];
3488 
3489   flp=(DOTFeatListPtr)GetObjectExtra((WindoW)ParentWindow(v));
3490   if (!flp) return;
3491 
3492   if (FindSegPrim(v, pt, NULL, NULL, &prim))
3493     {
3494       FindSegment(v, pt, &segID, &primID, &primCT);
3495       if (segID==1)
3496         dfp=flp->query_drp->dfp;
3497       else
3498         return;
3499       i=1;
3500       dfp=DOT_FindNextDfp(flp->featindex, dfp, TRUE);
3501       if (primID!=1)
3502         {
3503           for (; i<primID; i++)
3504             {
3505               dfp=DOT_FindNextDfp(flp->featindex, dfp, FALSE);
3506               if (dfp==NULL) return;
3507             }
3508         }
3509 
3510 
3511       if (dfp==NULL) return;
3512 
3513       data=(DOTSelDataPtr)flp->data;
3514       xmidPt=ABS(dfp->right+dfp->left)/2;
3515       data->q_start=xmidPt;
3516       GetPosition(data->vdp->panel, &rc);
3517       DOT_AddRectMargins(&rc, data->vdp);
3518       comp=data->vdp->comp;
3519       xmidPt=ABS(xmidPt-flp->mip->q_start);
3520       curpnt.x=MIN(rc.left+(xmidPt/comp), rc.right);
3521       
3522       DOT_PlaceCursors(v, seg, flp->segQCursor, flp->featindex, flp->query_drp, dfp->left, flp->fontHt, &(flp->vert_Qpos), TRUE, i);
3523       SetViewerProcs (v, DOT_QViewerClickProc, NULL, NULL, NULL);
3524       sprintf(infoBuf, "Hairs .. %s (x-axis)[%d]  vs.  %s (y-axis)[%d]", flp->mip->qname, data->q_start, flp->mip->sname, data->s_start);
3525       SetTitle(data->vdp->Infopanel,infoBuf);
3526       DOT_UpdateMainPanel(data->vdp, TRUE);
3527     }
3528 }
3529 
3530 static void DOT_SViewerClickProc(VieweR v, SegmenT seg, PoinT pt)
3531 {
3532   DOTFeatListPtr flp;
3533   DOTFeatPtr     dfp;
3534   DOTSelDataPtr  data;
3535   Char           infoBuf[255];
3536   RecT           rc;
3537   Int4           i, ymidPt, comp;
3538   Uint2          segID, primID, primCT;
3539   PrimitivE      prim;
3540 
3541 
3542   flp=(DOTFeatListPtr)GetObjectExtra((WindoW)ParentWindow(v));
3543   if (!flp) return;
3544 
3545   if (FindSegPrim(v, pt, NULL, NULL, &prim))
3546     {
3547       FindSegment(v, pt, &segID, &primID, &primCT);
3548       if (segID==1)
3549         dfp=flp->subject_drp->dfp;
3550       else
3551         return;
3552       i=1;
3553       dfp=DOT_FindNextDfp(flp->featindex, dfp, TRUE);
3554       if (primID!=1)
3555         {
3556           for (; i<primID; i++)
3557             {
3558               dfp=DOT_FindNextDfp(flp->featindex, dfp, FALSE);
3559               if (dfp==NULL) return;
3560             }
3561         }
3562 
3563 
3564       if (dfp==NULL) return;
3565 
3566       data=(DOTSelDataPtr)flp->data;
3567       ymidPt = ABS(dfp->right+dfp->left)/2;
3568       data->s_start=ymidPt;
3569       GetPosition(data->vdp->panel, &rc);
3570       DOT_AddRectMargins(&rc, data->vdp);
3571       ymidPt=ABS(ymidPt -flp->mip->s_start);
3572       comp=data->vdp->comp;
3573       curpnt.y=MIN(rc.top+(ymidPt/comp), rc.bottom);
3574 
3575       DOT_PlaceCursors(v, seg, flp->segSCursor, flp->featindex, flp->subject_drp, dfp->left, flp->fontHt, &(flp->vert_Spos), TRUE, i);
3576       SetViewerProcs (v, DOT_SViewerClickProc, NULL, NULL, NULL);
3577       sprintf(infoBuf, "Hairs .. %s (x-axis)[%d]  vs.  %s (y-axis)[%d]", flp->mip->qname, data->q_start, flp->mip->sname, data->s_start);
3578       SetTitle(data->vdp->Infopanel,infoBuf);
3579       DOT_UpdateMainPanel(data->vdp, TRUE);
3580     }
3581 }
3582 
3583 
3584 
3585 
3586 static void DOT_PlaceFeat(DOTFeatListPtr flp, SegmenT seg, Int4 yBase, DOTFeatPtr dfp, Int4 primID)
3587 {
3588   Char     str[50]; 
3589   Int4     xMargin;
3590   
3591   sprintf(str, "%s (%d,%d,%d)", dfp->label, dfp->left, dfp->right, ABS(dfp->right-dfp->left)); 
3592   AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
3593   xMargin=5;
3594     
3595   AddLabel(seg, xMargin, yBase, str, SMALL_TEXT, 0, UPPER_RIGHT, primID);
3596  
3597 }
3598 
3599 
3600 
3601 static void DOT_UpdateFeatViewer (DOTFeatListPtr flp, VieweR viewer, SegmenT seg, SegmenT segName, SegmenT segCursor, VwrClckProc click, DOTRowPtr drp, Int4 cur_pos, Int4Ptr vert_pos)
3602 {
3603   Int4 i;
3604   DOTFeatPtr dfeatp;
3605   DOTFeatIndexPtr fdindex;
3606 
3607   ExploreSegment(seg, NULL, DOT_DeletePrims);
3608   dfeatp=drp->dfp;
3609   fdindex=flp->featindex;
3610 
3611   i = 1;
3612   
3613   while (dfeatp != NULL)
3614     {
3615       if (fdindex[dfeatp->type].show)
3616         {
3617           DOT_PlaceFeat(flp, segName, (-1)*i*flp->fontHt, dfeatp, i);
3618           i++;
3619         }
3620       dfeatp=dfeatp->next;
3621     }
3622   if (i>1)
3623     {
3624       DOT_PlaceCursors(viewer, seg, segCursor, flp->featindex, drp, cur_pos, flp->fontHt, vert_pos, FALSE, 0);
3625       SetViewerProcs (viewer, click, NULL, NULL, NULL);
3626 
3627     }
3628   else
3629     {
3630       AddAttribute(seg, COLOR_ATT, RED_COLOR, 0,0,0,0);
3631       AddLabel(seg, 0, 0, "- no features -", SMALL_TEXT, 0, UPPER_RIGHT, 0);
3632       AttachPicture (viewer, seg, INT4_MIN, INT4_MAX, UPPER_LEFT,1 , 1, NULL); 
3633     }
3634 }
3635 /*_________________________________________________________________
3636 
3637   Function : DOT_PopFeatureViewers()
3638   
3639   Purpose : populate the Feature Viewer with the features.
3640 
3641 ___________________________________________________________________*/
3642 static void DOT_PopFeatureViewers(DOTFeatListPtr flp)
3643 {
3644   BioseqPtr query_bsp, subject_bsp;
3645   DOTPopFeat dpf;
3646   DOTRowPtr  drp1, drp2;
3647   Int2       fontH;
3648   DOTMainDataPtr mip;
3649 
3650   mip=flp->mip;
3651   if (!mip) return;
3652   drp1 = (DOTRowPtr)MemNew(sizeof(DOTRow));
3653   flp->query_drp=drp1;
3654   drp2=(DOTRowPtr)MemNew(sizeof(DOTRow));
3655   flp->subject_drp=drp2;
3656 
3657   fontH = FontHeight();
3658   flp->fontHt = fontH;
3659   /* seqmgrexplorefeatures goes through features in order left->right*/
3660   query_bsp=mip->qbsp;
3661   memset(&dpf, 0, sizeof(dpf));
3662   dpf.TopParentView=flp->Query;
3663   dpf.TopParentSeg= CreateSegment(flp->segQuery, 1, 0);
3664   dpf.nfeats = 1;
3665   dpf.fontHeight=fontH;
3666   dpf.drp=flp->query_drp; 
3667   dpf.dfp_cur=NULL;
3668   dpf.featindex=flp->featindex;
3669   flp->qFeatscount=SeqMgrExploreFeatures (query_bsp, (Pointer) &dpf, DOT_AddFeaturesToViewer, NULL, NULL, NULL);
3670 
3671   subject_bsp=mip->sbsp;
3672   memset(&dpf, 0, sizeof(dpf));
3673   dpf.TopParentView=flp->Subject;
3674   dpf.TopParentSeg= CreateSegment(flp->segSubject, 1, 0) ;
3675   dpf.nfeats = 1;
3676   dpf.fontHeight=fontH;
3677   dpf.drp=flp->subject_drp; 
3678   dpf.drp->dfp=NULL; 
3679   dpf.dfp_cur=NULL;
3680   dpf.featindex=flp->featindex;
3681   flp->sFeatscount=SeqMgrExploreFeatures (subject_bsp, (Pointer)&dpf, 
3682                           DOT_AddFeaturesToViewer, NULL, NULL, NULL);
3683 }
3684 
3685 static void DOT_HideAcceptProc(ButtoN b)
3686 {
3687 
3688 }
3689 
3690 static void DOT_HideFeatList(ButtoN b)
3691 {
3692     WindoW hHideDlg;
3693     DOTFeatListPtr flp;
3694     Int4 i, numrows;
3695     DOTFeatIndexPtr fdindex;
3696 
3697         hHideDlg = (WindoW)ParentWindow(b);
3698         if(hHideDlg == NULL) return;    
3699         flp = (DOTFeatListPtr) GetObjectExtra(hHideDlg);
3700    if(flp == NULL) return;
3701    numrows = flp->numrows;
3702    fdindex = flp->featindex;
3703 
3704     for(i = 1; i <= numrows; i++)
3705       {
3706         if(!GetItemStatus(flp->featList, i))
3707           {
3708             fdindex[fdindex[i].deref].show=FALSE;
3709           }
3710         else
3711           fdindex[fdindex[i].deref].show=TRUE;
3712       }
3713     DOT_UpdateFeatViewer(flp, flp->Query, flp->segQuery, flp->segQName, flp->segQCursor, DOT_QViewerClickProc, flp->query_drp, ((DOTSelDataPtr)flp->data)->q_start, &(flp->vert_Qpos));
3714     DOT_UpdateFeatViewer(flp, flp->Subject, flp->segSubject, flp->segSName, flp->segSCursor, DOT_SViewerClickProc, flp->subject_drp, ((DOTSelDataPtr)flp->data)->s_start, &(flp->vert_Spos));
3715     
3716     Remove(hHideDlg);
3717 }
3718 
3719 static void DOT_SetHideList(DOTFeatListPtr flp)
3720 {
3721   Int4 i;
3722   DOTFeatIndexPtr fdindex;
3723   
3724   fdindex=flp->featindex;
3725 
3726   for(i = 1; i <= FEATDEF_MAX; i++) 
3727     {
3728       if (fdindex[fdindex[i].deref].present)
3729         {
3730           if (fdindex[fdindex[i].deref].show)
3731             SetItemStatus(flp->featList, i, TRUE);
3732           else
3733             SetItemStatus(flp->featList, i, FALSE);
3734         }
3735     }
3736 }
3737 
3738 static void DOT_HideFeatDlg(DOTFeatListPtr flp)
3739 {
3740     Int4 i, numrows;
3741     GrouP g, hg;
3742     ButtoN b;
3743     DOTFeatIndexPtr fdindex;
3744 
3745     if (flp==NULL) return;
3746     flp->hFeatDlg=NULL;
3747 
3748     flp->hFeatDlg = MovableModalWindow(-50, -20, -10, -10, "Hide/Show Features", NULL);
3749     if (flp->hFeatDlg==NULL) return;
3750 
3751     SetObjectExtra (flp->hFeatDlg, (void *)flp, NULL);
3752 
3753 
3754     hg = HiddenGroup(flp->hFeatDlg, 1, 2, NULL);
3755     g = NormalGroup(hg, 1, 2, "Choose Features to show:", systemFont, NULL);
3756 
3757     fdindex = flp->featindex;
3758     flp->featList = MultiList(g,20, 6, NULL);
3759     numrows=1;
3760     for(i = 1; i < FEATDEF_MAX; i++) 
3761       {
3762         if (fdindex[i].present)
3763           {
3764             ListItem(flp->featList, fdindex[i].label);
3765             fdindex[numrows].deref=i;
3766             numrows++;
3767           }   
3768       }
3769     DOT_SetHideList(flp);
3770 
3771     flp->numrows=numrows-1;
3772     g = HiddenGroup(hg, 2, 1, NULL);
3773     SetGroupSpacing(g, 15, 15);
3774     b = DefaultButton(g, "OK", (BtnActnProc) DOT_HideFeatList);
3775 
3776     Show(flp->hFeatDlg);
3777     return;
3778 }
3779 
3780 static void DOT_HideFeatDlgItem(IteM i)
3781 {
3782   DOTFeatListPtr flp;
3783   WindoW         FeatWin;
3784 
3785   FeatWin=(WindoW)ParentWindow(i);
3786   if (FeatWin==NULL)return;
3787 
3788   flp=(DOTFeatListPtr)GetObjectExtra(FeatWin);
3789   DOT_HideFeatDlg(flp);
3790 }
3791 
3792 /*________________________________________(DOT_BuildFeatGUI)_____________
3793 
3794   Purpose : Creates viewers for Features.
3795 
3796 ____________________________________________________________________*/
3797 
3798 static WindoW DOT_BuildFeatGUI (DOTFeatListPtr flp)
3799 {
3800   WindoW  FeatWin;
3801   DOTMainDataPtr mip;
3802   MenU    m1;
3803   VieweR  v1, v2;
3804   SegmenT seg1, seg2;
3805   GrouP   subg1, subg2, g;
3806   Int2   Margins;
3807   Char   str[255];
3808 
3809         if (!flp) return(NULL);
3810 
3811         Margins=10*stdCharWidth;
3812         FeatWin = DocumentWindow(Margins,Margins ,-10, -10,"Features", NULL, DOT_ResizeFeatWindow);
3813    if (!FeatWin) return(NULL);
3814    SetObjectExtra (FeatWin, (Pointer) flp, NULL);
3815 
3816    flp->FeatWin=FeatWin;
3817 
3818    m1 = PulldownMenu (FeatWin, "Options");
3819    CommandItem(m1, "Hide ..", DOT_HideFeatDlgItem);
3820    CommandItem(m1, "Close", DOT_CloseFeatWindow);
3821 
3822         mip= flp->mip;
3823 
3824 
3825         g=HiddenGroup(FeatWin,2,0,NULL);
3826 
3827    subg1=HiddenGroup(g, 0, 2, NULL);
3828    sprintf(str, "%s(x-axis)", mip->qname);
3829    flp->QInfo=StaticPrompt (subg1, str , 0, 0 , systemFont, 'l');
3830         v1=CreateViewer(subg1, 150 , 200, TRUE, TRUE);  
3831         seg1=CreatePicture();
3832    
3833 /*    AlignObjects(ALIGN_JUSTIFY, (HANDLE) pr1, (HANDLE) v1, NULL, NULL); */
3834 
3835         /*viewer for close up of features*/
3836    subg2=HiddenGroup(g, 0, 2, NULL);
3837    sprintf(str, "%s(y-axis)", mip->sname);
3838    flp->SInfo= StaticPrompt (subg2, str , 0, 0, systemFont, 'l');
3839    v2 = CreateViewer(subg2, 150,200,TRUE,TRUE);
3840    seg2 = CreatePicture();
3841  
3842    flp->Query=v1;
3843    flp->segQuery=seg1;
3844         flp->Subject=v2; /* lines on the control panel*/
3845         flp->segSubject=seg2;
3846    flp->segQName =CreateSegment(flp->segQuery, 1, 0);
3847    flp->segSName=CreateSegment(flp->segSubject, 1, 0);
3848    flp->segQCursor=CreateSegment(flp->segQuery, 2, 0);
3849    flp->segSCursor=CreateSegment(flp->segSubject, 2, 0);
3850 
3851 /*    AlignObjects(ALIGN_JUSTIFY, (HANDLE) pr2, (HANDLE) v2, NULL, NULL); */
3852 
3853    RealizeWindow(FeatWin);
3854    DOT_ResizeFeatWindow(FeatWin);
3855 
3856         return(FeatWin);        
3857 }
3858 
3859 typedef struct dot_goto{
3860   TexT   txt;
3861   ButtoN highlight;
3862 } DOTGoto, PNTR DOTGotoPtr;
3863 
3864 static void DOT_GotoProc(ButtoN b, TexT txt, Int4 value)
3865 {
3866   DOTSelDataPtr data;
3867   DOTVibDataPtr vdp2=NULL;
3868   Int4       pos=0, margin, q_start, s_start;
3869   Int4       xstart, xstop, ystart, ystop;
3870   Int4       Qstart, Sstart;
3871   RecT       rc;
3872   DOTAlnPtr  salp;
3873 
3874 
3875   vdp2=(DOTVibDataPtr)GetObjectExtra(ParentWindow(b));
3876   if(!vdp2) return;
3877   data= vdp2->data;
3878   salp = vdp2->sv->salp;
3879   if (salp->show == dot_plot){
3880     xstart = data->q_start+data->xstart;
3881     xstop = data->q_start+data->xstop;
3882     ystart = data->s_start+data->ystart;
3883     ystop = data->s_start+data->ystop;
3884     Qstart = data->q_start;
3885     Sstart = data->s_start;
3886   }
3887   else {
3888     xstart = salp->q_start;
3889     xstop = salp->q_stop;
3890     ystart = salp->s_start;
3891     ystop = salp->s_stop;
3892     Qstart = salp->q_start;
3893     Sstart = salp->s_start;
3894   }
3895 
3896   pos=DOT_GetValue(txt);
3897   if (1 == value){
3898     if (pos<xstart)
3899       pos=xstart;
3900     if (pos>xstop)
3901       pos=xstop;
3902     q_start=pos-Qstart;
3903     q_start=q_start+q_start/10;
3904     pos=DOT_WorldtoScreen(q_start,vdp2->charw/2);
3905   }
3906   else if (2 == value){
3907     if (pos<ystart)
3908       pos=ystart;
3909     if (pos>ystop)
3910       pos=ystop;
3911     s_start=pos-Sstart;
3912     s_start=s_start+s_start/10;
3913     pos=DOT_WorldtoScreen(s_start,vdp2->charw/2);
3914   }
3915 
3916   GetPosition(vdp2->sv->v2, &rc);
3917   margin=MAX((StringWidth(vdp2->xname)), (StringWidth(vdp2->yname)))+10;
3918   vdp2->sv->barp=pos+rc.left+margin;
3919   AttachPicture(vdp2->sv->v2, vdp2->sv->pict2, vdp2->sv->barp, INT4_MIN, UPPER_CENTER, 1, 1, NULL);
3920 }
3921 
3922 static void DOT_TopProc(ButtoN b)
3923 {
3924   DOTGotoPtr   gtp;
3925 
3926   gtp = (DOTGotoPtr)GetObjectExtra(b);
3927   DOT_GotoProc(b, gtp->txt, 1);
3928 }
3929 
3930 static void DOT_BottomProc(ButtoN b)
3931 {
3932   DOTGotoPtr   gtp;
3933 
3934   gtp = (DOTGotoPtr)GetObjectExtra(b);
3935   DOT_GotoProc(b, gtp->txt, 2);
3936 }
3937 
3938 /*_______________________________________________(DOT_SVSwitchDisplay)___
3939 
3940   Purpose : Change Display between Dotplot and Blast hits
3941 
3942 ____________________________________________________________________*/
3943 
3944 
3945 static void DOT_SVSwitchDisplay(PopuP p)
3946 
3947 {
3948   DOTVibDataPtr       vdp2=NULL;
3949   WindoW              w;
3950   Int4                value;
3951   DOTGotoPtr          gtp=NULL;
3952   
3953 
3954   gtp = (DOTGotoPtr) GetObjectExtra(p);
3955   w=(WindoW)ParentWindow(p);
3956   vdp2=(DOTVibDataPtr)GetObjectExtra(w);
3957   if (!vdp2 || !vdp2->alp) return;
3958 
3959   SetTitle(gtp->txt, "");
3960   value=GetValue(p);
3961   
3962   if (value==1) /* dot plot */
3963     {
3964       vdp2->showDotPlot=TRUE;
3965       vdp2->showALIGN=FALSE;
3966     }
3967   else if (value==2) /* blast aligns */
3968     {
3969       vdp2->showDotPlot=FALSE;
3970       vdp2->showALIGN=TRUE;
3971     }
3972   else if (value==3) /* both */
3973     {
3974       vdp2->showDotPlot=TRUE;
3975       vdp2->showALIGN=TRUE;
3976     }
3977 
3978   DOT_SVPopulateDiagViewer(vdp2);
3979   if (vdp2->sv->salp){
3980     MemFree(vdp2->sv->salp);
3981     vdp2->sv->salp=NULL;
3982   }
3983   DOT_SVPopulateSequenceViewer(vdp2);
3984 
3985 }
3986 
3987 static void DOT_HighlightProc(ButtoN b)
3988 {
3989   DOTVibDataPtr vdp2 = NULL;
3990   DOTGotoPtr    gtp = NULL;
3991 
3992   gtp = (DOTGotoPtr) GetObjectExtra(b);
3993   vdp2 = (DOTVibDataPtr)GetObjectExtra(ParentWindow(b));
3994   if (!vdp2 || !gtp) return;
3995   
3996   if (vdp2->sv->highlight == SHOW_MISMATCHES) {
3997     vdp2->sv->highlight = SHOW_MATCHES;
3998     SetTitle (gtp->highlight, "Show Mismatches");
3999   }
4000   else {
4001     vdp2->sv->highlight = SHOW_MISMATCHES;
4002     SetTitle (gtp->highlight, "Show Matches");
4003   }
4004   DOT_SVPopulateSequenceViewer(vdp2);
4005 
4006 }
4007 
4008 
4009 /*________________________________________(DOT_SVBuildDiagViewer)_____________
4010 
4011   Purpose : Creates viewers for second window.
4012 
4013 ____________________________________________________________________*/
4014 
4015 static WindoW DOT_SVBuildDiagViewer(DOTVibDataPtr vdp2)
4016 {
4017   WindoW    wSequence;
4018   GrouP     g, g2, s, s2, s3, s4;
4019   PrompT    pr1, pr2; 
4020   VieweR    v1,v2;
4021   ButtoN    b;
4022   RecT      rc;
4023   SegmenT   pict1,pict2;
4024   Int2      Margins, pixwidth; 
4025   Char      zoombuf[]={"Decrease scale to zoom in .."};
4026   Char      str1[41]={""}, str2[41]={""};
4027   DOTGotoPtr   gtp;
4028   DOTMainDataPtr mip;
4029   Char      title[60]={""};
4030 
4031         if (!vdp2) return(NULL);   
4032 
4033         Margins=10*stdCharWidth;
4034    sprintf(title, "%s", vdp2->xname);
4035    StringCat(title, "  vs. ");
4036    StringCat(title, vdp2->yname);
4037         wSequence = DocumentWindow(Margins,Margins ,-10, -10, title, NULL, DOT_ResizeSequenceWindow);
4038         if (!wSequence) return(NULL);
4039    GetPosition (wSequence,&rc);
4040    pixwidth=1200; /* some approximate value */
4041    /* first top group */
4042    s = HiddenGroup (wSequence,1, 4, NULL);
4043    /*threshold bar*/
4044    s3 = HiddenGroup (s,5, 0, NULL);
4045    pr2=StaticPrompt (s3, "Threshold-Ramp:", 0, 3*vdp2->Fh/2,vdp2->Fnt, 'l');
4046    pr1=StaticPrompt (s3, "  20%", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4047    vdp2->sdp.ScrollBar = ScrollBar (s3, 15, 5, DOT_ChangeSequenceViewerCutoff);
4048    pr1=StaticPrompt (s3, "100%", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4049    PushButton(s3, "Close", DOT_CloseSequenceWindow);
4050    SetObjectExtra(vdp2->sdp.ScrollBar, vdp2, NULL);
4051    CorrectBarMax (vdp2->sdp.ScrollBar, 80); /* 100% */
4052    CorrectBarValue (vdp2->sdp.ScrollBar, 60);/* 100% */
4053    /* second top group */
4054    s2 = HiddenGroup (s, 0, 2, NULL);
4055    if (vdp2->mip && vdp2->alp){
4056      s4=HiddenGroup (s2, 4, 0, NULL);
4057 
4058    }
4059    else{
4060      s4=HiddenGroup(s2, 2, 0, NULL);
4061    }
4062    SetGroupMargins(s4, 10, 10);
4063    SetGroupSpacing(s4, 10,10);
4064 
4065    pr1 = StaticPrompt (s4, zoombuf, StringWidth(zoombuf)+10 , popupMenuHeight, vdp2->Fnt, 'l');
4066 #ifdef WIN_MAC
4067    vdp2->sv->scale = PopupList (s4, TRUE, DOT_SVChangeScale);
4068 #endif
4069 
4070 #ifndef WIN_MAC
4071    vdp2->sv->scale = PopupList (s4, FALSE, DOT_SVChangeScale);
4072 #endif
4073    if (vdp2->mip)
4074      vdp2->showDotPlot=TRUE;
4075    if (vdp2->alp){
4076      vdp2->showALIGN=TRUE;
4077    }
4078    if (vdp2->mip && vdp2->alp){
4079 /*      pr1 = StaticPrompt (s4, "", StringWidth(zoombuf)+10 , popupMenuHeight, vdp2->Fnt, 'l'); */
4080      vdp2->sv->showp=PopupList (s4, FALSE, DOT_SVSwitchDisplay);
4081      PopupItem (vdp2->sv->showp, "- dot plot -");
4082      PopupItem (vdp2->sv->showp, "- blast -");
4083      PopupItem (vdp2->sv->showp, "- both -");
4084      SetValue (vdp2->sv->showp, 1);
4085    }
4086    sprintf(vdp2->iInfo,"Diag not selected");
4087    vdp2->Infopanel= StaticPrompt (s2, vdp2->iInfo, pixwidth, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4088    SetObjectExtra (vdp2->sv->scale, vdp2, NULL);
4089         v1=CreateViewer(s,600,500,TRUE,TRUE);
4090         pict1=CreatePicture();
4091    /* bottom group */
4092         g=HiddenGroup(wSequence,0,2,NULL);
4093    g2=HiddenGroup(g, 8, 0, NULL);
4094    SetGroupMargins(g2, 10, 10);
4095    SetGroupSpacing(g2, 10, 10);
4096    gtp=(DOTGotoPtr)MemNew(sizeof(DOTGoto));
4097    SetObjectExtra (vdp2->sv->showp, (Pointer) gtp, NULL);
4098    vdp2->Ggoto=g2;
4099    mip=vdp2->mip;
4100    StaticPrompt (g2, "    -Goto-", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4101    gtp->txt = DialogText (g2, "", (Int2)4, NULL);
4102    StaticPrompt (g2, "  on  ", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4103    MemSet((Pointer)title, '\0', sizeof(title));
4104    sprintf(title, "  Top  ");
4105    b=PushButton (g2, title, DOT_TopProc);
4106    StaticPrompt (g2, " or ", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4107    SetObjectExtra(b, (Pointer)gtp, StdCleanupExtraProc);
4108 
4109    MemSet((Pointer)title, '\0', sizeof(title));
4110    sprintf(title, "  Bottom  ");
4111    b=PushButton (g2, title, DOT_BottomProc);
4112    SetObjectExtra(b, (Pointer)gtp, NULL);
4113    StaticPrompt (g2, "  sequence       ", 0, 3*vdp2->Fh/2, vdp2->Fnt, 'l');
4114    gtp->highlight = PushButton (g2, "Show Mismatches", DOT_HighlightProc);
4115    vdp2->sv->highlight = SHOW_MATCHES;
4116    SetObjectExtra(gtp->highlight, (Pointer)gtp, NULL);
4117    Disable(g2);
4118 
4119         v2=CreateViewer(g,600,150,FALSE,TRUE);
4120         pict2=CreatePicture();
4121 
4122         vdp2->sv->w=wSequence;
4123         vdp2->sv->v1=v1;
4124         vdp2->sv->pict1=pict1;
4125         vdp2->sv->v2=v2;
4126         vdp2->sv->pict2=pict2;
4127 
4128         SetObjectExtra (vdp2->sv->w, (Pointer) vdp2, NULL);
4129         AlignObjects(ALIGN_JUSTIFY, (HANDLE) v2, (HANDLE)g, NULL, NULL);
4130         SetColorCell((GraphiC)vdp2->sv->v1, 0,0,255,192);
4131 
4132    RealizeWindow(wSequence);
4133    DOT_ResizeSequenceWindow(wSequence);
4134 
4135   /* calculate initial scale */
4136    DOT_SVCalculateScaling(vdp2);
4137 
4138         /*populate the viewer : hits*/
4139    if (DOT_SVPopulateDiagViewer(vdp2)==FALSE)
4140     goto end;
4141 
4142   if (DOT_SVPopulateSequenceViewer(vdp2)==FALSE)
4143     goto end;
4144 
4145   return(wSequence);    
4146 
4147  end:
4148    
4149    ErrPostEx (SEV_WARNING, 0, 0, "%s", "Display functions failed");
4150    return NULL;
4151 
4152 }
4153 
4154 /*________________________________________(DOT_UpdateDataRects)_____________
4155 
4156   Purpose : Updates main window rect params in data struct.
4157 
4158 ____________________________________________________________________
4159 */
4160 static void DOT_UpdateDataRects (DOTSelDataPtr data, RecT rc, DOTVibDataPtr vdp, Boolean updateSelectedRect)
4161 {
4162   Int4  width, height, VFrom=vdp->sdp.VFrom, HFrom=vdp->sdp.HFrom;
4163   Int4  comp, dx, dy, xstart, ystart;
4164 
4165 
4166   DOT_AddRectMargins(&rc, vdp);
4167 
4168   /* update the limits of selectable region of parent window */
4169   width=MIN (rc.right-rc.left, vdp->curr_qlen - HFrom );
4170   height=MIN (rc.bottom-rc.top, vdp->curr_slen - VFrom );
4171     
4172   data->rcP.left=rc.left;
4173   data->rcP.top=rc.top;
4174   data->rcP.right=rc.left+width+2;
4175   data->rcP.bottom=rc.top+height+2;
4176 
4177   /* update the size of selected rect */
4178   if (updateSelectedRect)
4179     {
4180       xstart=ABS(data->q_start-vdp->xstart);
4181       ystart=ABS(data->s_start-vdp->ystart);      
4182       comp=vdp->comp;
4183       dx=data->H_pos-HFrom;
4184       dy=data->V_pos-VFrom;
4185       width=ABS(data->q_stop-data->q_start)/comp;
4186       height=ABS(data->s_stop-data->s_start)/comp;
4187 
4188       data->rcS.left=rc.left+((xstart)/comp)/* -HFrom */;
4189       data->rcS.right=data->rcS.left+width;
4190       data->rcS.top=rc.top+((ystart)/comp)/* -VFrom */;
4191       data->rcS.bottom=data->rcS.top+height;
4192     }
4193 }
4194 
4195 static void DOT_InitFeatIndex(DOTFeatIndexPtr fdindex)
4196 {
4197   Int4  i;
4198 
4199   for(i=1; i<FEATDEF_MAX; i++)
4200     {
4201       fdindex[i].show=TRUE;
4202     }
4203 }
4204 
4205 /*________________________________________(DOT_MsgFunc)_____________
4206 
4207   Purpose : Message Callback for the 2nd window.
4208 
4209 ____________________________________________________________________*/
4210 static Int2 LIBCALLBACK DOT_MsgFunc (OMMsgStructPtr ommsp)
4211 {
4212   DOTVibDataPtr vdp2 = NULL;
4213   OMUserDataPtr      omudp;
4214 
4215 
4216 
4217   omudp = (OMUserDataPtr)(ommsp->omuserdata);
4218   vdp2 = (DOTVibDataPtr)omudp->userdata.ptrvalue;
4219 
4220   switch (ommsp->message)
4221     {
4222     case OM_MSG_DEL:
4223       break;
4224     case OM_MSG_CREATE:
4225       break;
4226     case OM_MSG_UPDATE:
4227       break;
4228     case OM_MSG_SELECT:
4229       
4230      break;
4231    case OM_MSG_DESELECT:
4232      break;
4233     case OM_MSG_CACHED:
4234       break;
4235     case OM_MSG_UNCACHED:
4236       break;
4237     case OM_MSG_TO_CLIPBOARD: 
4238       break;
4239     case OM_MSG_SETCOLOR:
4240       break;
4241     case OM_MSG_FLUSH:
4242       break;
4243     default:
4244       break;
4245     }
4246 
4247   return OM_MSG_RET_OK;
4248     
4249 }
4250 
4251 
4252 /*________________________________________(DOT_ClickProc)_____________
4253 
4254   Purpose : Click proc for main window - no action.
4255 
4256 ____________________________________________________________________*/
4257 static void DOT_ClickProc (PaneL p, PoinT pt)
4258 {
4259   DOTSelDataPtr   data;
4260   RecT        rc, prc;
4261   DOTVibDataPtr  vdp;
4262 
4263 
4264   ObjectRect(p, &prc);
4265 /*   data = (DOTSelDataPtr) GetObjectExtra (p); */
4266   vdp = (DOTVibDataPtr)GetObjectExtra(ParentWindow(p));
4267   if(vdp==NULL) return;
4268   data=(DOTSelDataPtr)vdp->data;
4269   if (!data) return;
4270 
4271   /* specify clickable region */
4272   DOT_UpdateDataRects(data, prc, vdp, FALSE);
4273 
4274   
4275   rc = data->rcP;
4276 
4277   if (!PtInRect (pt, &rc)) 
4278     {
4279       if (pt.y < rc.top) pt.y = rc.top;
4280       if (pt.y > rc.bottom) pt.y = rc.bottom;
4281       if (pt.x < rc.left) pt.x = rc.left;
4282       if (pt.x > rc.right) pt.x = rc.right;
4283     }
4284 
4285   fstpnt = pt;
4286   curpnt = pt;
4287   
4288   InvertMode();
4289   if (vdp->selectMode==dot_SEQVIEW)
4290     DOT_SelectFrameProc (p);
4291   else
4292     DOT_SelectLineProc(p);
4293 
4294   if (data->selected)
4295     data->rm_lastselected=TRUE;
4296   else
4297     data->selected=TRUE;
4298 
4299   SetObjectExtra(p, data, NULL);
4300 
4301 }
4302 
4303 /*________________________________________(DOT_DragProc)_____________
4304 
4305   Purpose : Drag proc for main window - no action.
4306 
4307 ____________________________________________________________________*/
4308 static void DOT_DragProc (PaneL p, PoinT pt)
4309 {
4310   DOTSelDataPtr data;
4311   RecT      rc;
4312   DOTVibDataPtr vdp;
4313 
4314   vdp=(DOTVibDataPtr)GetObjectExtra(ParentWindow(p));
4315   if (vdp==NULL) return;
4316   data = (DOTSelDataPtr) GetObjectExtra (p);
4317   
4318 
4319 
4320   InvertMode();
4321   if (vdp->selectMode == dot_SEQVIEW)
4322     DOT_SelectFrameProc(p);
4323   else
4324     DOT_SelectLineProc(p);
4325   
4326   rc=data->rcP;
4327 
4328 
4329   if (!PtInRect (pt, &rc)) 
4330     {
4331       if (pt.y < rc.top) pt.y = rc.top;
4332       if (pt.y > rc.bottom) pt.y = rc.bottom;
4333       if (pt.x < rc.left) pt.x = rc.left;
4334       if (pt.x > rc.right) pt.x = rc.right;
4335     }
4336 
4337   curpnt = pt;
4338   
4339   if (vdp->selectMode==dot_SEQVIEW)
4340     DOT_SelectFrameProc(p);
4341   else
4342     DOT_SelectLineProc(p);
4343     
4344   
4345   if (data->selected)
4346     {
4347       data->rm_lastselected=TRUE;
4348     }
4349   else
4350     data->selected = TRUE;
4351   
4352   SetObjectExtra(p, data, NULL);
4353 
4354 }
4355 
4356 
4357 /*__________________________(DOT_ReleaseProc)_____________
4358 
4359   Purpose : Release Proc for main window - calls up second window.
4360 
4361 ________________________________________________________*/
4362 static void DOT_ReleaseProc(PaneL p, PoinT pt)
4363 {
4364   DOTSelDataPtr   data;
4365   Int4        VFrom, HFrom;
4366   DOTVibDataPtr  vdp2=NULL, vdp=NULL;
4367   DOTMainDataPtr mip1=NULL;
4368   DOTAlignInfoPtr alp=NULL;
4369   DOTFeatListPtr     flp;
4370   Boolean     xaxis_incr=TRUE, yaxis_incr=TRUE;
4371   RecT        rc;
4372   Int2        dx, dy;
4373   Char        infoBuf[255];
4374   
4375 
4376 
4377   vdp = (DOTVibDataPtr)GetObjectExtra(ParentWindow(p));
4378   if (!vdp) return;
4379 
4380   data = (DOTSelDataPtr) vdp->data;
4381 
4382   if (!data->selected) return;
4383 
4384   rc = data->rcP;
4385 
4386   if (!PtInRect (pt, &rc)) 
4387     {
4388       if (pt.y < rc.top) pt.y = rc.top;
4389       if (pt.y > rc.bottom) pt.y = rc.bottom;
4390       if (pt.x < rc.left) pt.x = rc.left;
4391       if (pt.x > rc.right) pt.x = rc.right;
4392     }
4393   curpnt = pt;
4394   mip1 = vdp->mip;
4395   alp=vdp->alp;
4396 
4397   VFrom  = vdp->sdp.VFrom; 
4398   HFrom = vdp->sdp.HFrom;
4399 
4400 
4401   
4402   if (vdp->selectMode == dot_SEQVIEW)
4403     {
4404       DOT_UpdatePt();
4405       if (vdp->ChildWin==NULL)
4406         vdp2=(DOTVibDataPtr) MemNew (sizeof(DOTVibData));
4407       else
4408         {
4409           vdp2 = (DOTVibDataPtr)GetObjectExtra(vdp->ChildWin);
4410           vdp->ChildWin=DOT_ClearLastWindow(vdp->ChildWin, TRUE);
4411         }
4412 /*       if (vdp2==NULL) return; */
4413 
4414       InvertMode();
4415       DOT_SelectFrameProc(p);
4416 
4417       dx=HFrom-data->H_pos;
4418       dy=VFrom-data->V_pos;
4419       
4420       /* previous rect coordinates */
4421       data->old_rcS.left=data->rcS.left-dx;
4422       data->old_rcS.right=data->rcS.right-dx;
4423       data->old_rcS.top=data->rcS.top-dy;
4424       data->old_rcS.bottom=data->rcS.bottom-dy;
4425       /* new rect coordinates on parent window */
4426       data->rcS.left = fstpnt.x;
4427       data->rcS.top = fstpnt.y;
4428       data->rcS.right = curpnt.x;
4429       data->rcS.bottom = curpnt.y;      
4430       data->H_pos=HFrom;
4431       data->V_pos=VFrom;      
4432   /* map selected region to sequence(world) coordinates 
4433      plus or minus one to account for errors when rounding off */
4434 
4435       data->q_start = MAX((fstpnt.x  - rc.left  + HFrom - 1)*vdp->comp, 0) + vdp->xstart;
4436       data->q_stop = MIN(((curpnt.x - rc.left +(HFrom+1))*vdp->comp)+vdp->xstart, vdp->xstop);
4437  
4438       data->s_start = MAX((fstpnt.y  - rc.top   + (VFrom-1))*vdp->comp, 0) + vdp->ystart;
4439       data->s_stop = MIN(((curpnt.y - rc.top +(VFrom+1))*vdp->comp)+vdp->ystart, vdp->ystop);
4440       
4441       data->qlen=ABS(data->q_stop-data->q_start)+1;
4442       data->slen=ABS(data->s_stop-data->s_start)+1;
4443 
4444       /* create new sequence buffers */
4445       DOT_InitCInfo(vdp, vdp2, data);
4446 
4447       if (vdp2->mip){
4448         DOT_FillNewSeqBufs(vdp, vdp2, FALSE);
4449 /*         DOT_GetSeqs(vdp2->mip, TRUE); */
4450         if (DOT_BuildHitList(vdp2->mip, TRUE, TRUE)<0)
4451           {
4452             data->selected=FALSE;
4453             data->rm_lastselected =TRUE;
4454             SetTitle(vdp->Infopanel, vdp->iInfo);
4455             DOT_UpdateMainPanel(vdp, FALSE);
4456             Beep();
4457             return;/* no hits */
4458           }
4459       }
4460     /*reset infopanel*/
4461       
4462       sprintf(infoBuf, "Selected ..   %s (horizontal) [%d..%d]   vs.   %s (vertical) [%d..%d]", vdp->xname, data->q_start, data->q_stop, vdp->yname, data->s_start, data->s_stop);
4463       SetTitle(vdp->Infopanel,infoBuf);
4464       DOT_UpdateMainPanel(vdp, FALSE);
4465       
4466       /* create second window */
4467 
4468       vdp->ChildWin=DOT_SVBuildDiagViewer(vdp2);
4469 
4470     }
4471   else if (vdp->selectMode == dot_FEATVIEW && vdp->mip)
4472     {
4473       InvertMode();
4474       DOT_SelectLineProc(p);     
4475       dx=HFrom-data->H_pos;
4476       dy=VFrom-data->V_pos;
4477       /* previous hair coordinates */
4478       data->old_rcS.left=data->rcS.left-dx;
4479       data->old_rcS.right=data->rcS.right-dx;
4480       data->old_rcS.top=data->rcS.top-dy;
4481       data->old_rcS.bottom=data->rcS.bottom-dy;
4482       /* new hair coordinates on parent window */
4483       data->rcS.left = curpnt.x;
4484       data->rcS.top = curpnt.y;
4485       data->rcS.right = curpnt.x;
4486       data->rcS.bottom = curpnt.y;
4487       data->H_pos=HFrom;
4488       data->V_pos=VFrom;
4489       if (vdp->strand1 == Seq_strand_plus)
4490         {
4491           data->q_start = MIN(MAX((curpnt.x - rc.left +(HFrom))*vdp->comp, 0)+vdp->xstart, vdp->xstop);
4492         }
4493       else
4494         {
4495           data->q_start = MAX(vdp->xstart-((curpnt.x - rc.left +(HFrom))*vdp->comp), vdp->xstop);
4496         }
4497       
4498       if (vdp->strand2==Seq_strand_plus)
4499         {
4500           data->s_start = MIN(MAX((curpnt.y - rc.top +(VFrom))*vdp->comp, 0)+ vdp->ystart, vdp->ystop);
4501         }
4502       else
4503         {
4504           data->s_start = MAX(vdp->ystart-((curpnt.y - rc.top + (VFrom))*vdp->comp), vdp->ystop);
4505         }
4506 
4507       DOT_UpdateMainPanel(vdp, TRUE);
4508       /* look for features in selected region */
4509 
4510       if (vdp->ChildWin !=NULL)
4511         {
4512           flp=(DOTFeatListPtr)GetObjectExtra(vdp->ChildWin);
4513         }
4514       else /* first pass */
4515         {
4516           flp=(DOTFeatListPtr)MemNew(sizeof(DOTFeatList));
4517           flp->data=vdp->data;
4518           flp->mip=vdp->mip;
4519           flp->featindex=(DOTFeatIndexPtr) MemNew(sizeof(DOTFeatIndex)*FEATDEF_MAX);
4520           DOT_InitFeatIndex(flp->featindex);
4521           vdp->ChildWin=DOT_BuildFeatGUI(flp);
4522           if (!vdp->ChildWin) return;
4523           DOT_PopFeatureViewers(flp);
4524           if (flp->qFeatscount==0 && flp->sFeatscount==0)
4525             {
4526               data->selected=FALSE;
4527               DOT_UpdateMainPanel(vdp, TRUE);
4528               MemFree(flp);
4529               ErrPostEx(SEV_WARNING, 0, 0, "no features on bioseqs");
4530               return;
4531             }
4532         }
4533       
4534       DOT_UpdateFeatViewer(flp, flp->Query, flp->segQuery, flp->segQName, flp->segQCursor, DOT_QViewerClickProc, flp->query_drp, ((DOTSelDataPtr)flp->data)->q_start, &(flp->vert_Qpos));
4535       DOT_UpdateFeatViewer(flp, flp->Subject, flp->segSubject, flp->segSName, flp->segSCursor, DOT_SViewerClickProc, flp->subject_drp, ((DOTSelDataPtr)flp->data)->s_start, &(flp->vert_Spos));
4536       sprintf(infoBuf, "Hairs .. X-axis (%s) [%d]  vs.  Y-axis (%s) [%d]", vdp->xname, data->q_start, vdp->yname, data->s_start);
4537       SetTitle(vdp->Infopanel,infoBuf);
4538       
4539     }
4540 
4541   Show(vdp->ChildWin);
4542 }
4543 
4544 /*________________________________________(DOT_InitDataStruct)_____________
4545 
4546   Purpose : Initialize data structure.
4547 
4548 ____________________________________________________________________*/
4549 static void DOT_InitDataStruct (DOTVibDataPtr vdp)
4550 {
4551   DOTSelDataPtr data;
4552   RecT       rc;
4553   
4554   
4555   ObjectRect(vdp->panel, &rc);
4556   InsetRect(&rc, 4, 4);
4557 
4558   data = (DOTSelDataPtr) MemNew (sizeof (DOTSelData));
4559   data->selected = FALSE;
4560   data->q_start = 0;
4561   data->q_stop = 0;
4562   data->s_start = 0;
4563   data->s_stop = 0;
4564   data->V_pos=0;
4565   data->H_pos=0;
4566   data->vdp = vdp;
4567   DOT_UpdateDataRects(data, rc, vdp, FALSE);
4568   /* initialize document left and top parameters */
4569 
4570 
4571   vdp->data = (VoidPtr)data;
4572   if (vdp->panel != NULL) 
4573     SetObjectExtra (vdp->panel, data, NULL);
4574   else
4575     return;
4576 }
4577 /*________________________________________(DOT_ReducesizeProc)_____________
4578   
4579 Purpose : Increase compression of main window display.
4580 
4581 ____________________________________________________________________*/
4582 
4583 static void DOT_ReduceSizeProc (IteM i) 
4584 {
4585   WindoW      w, temport;
4586   RecT        rcP;
4587   DOTVibDataPtr  vdp;
4588   DOTSelDataPtr   data;
4589   Int4        VCurPos, HCurPos;
4590   BaR         vsb, hsb;
4591 
4592   
4593 
4594   w = (WindoW)ParentWindow(i);
4595   temport = SavePort(w);
4596 
4597   vdp = (DOTVibDataPtr)GetObjectExtra (w);
4598   if (vdp==NULL) return;
4599 
4600   data=(DOTSelDataPtr)vdp->data;
4601 
4602   Select(vdp->panel);
4603   ObjectRect(vdp->panel, &rcP);
4604 
4605   vdp->comp *=2;
4606  
4607   DOT_SetCurrSeqlen (vdp);
4608   DOT_SetScrlVals (vdp);
4609 
4610   vdp->sdp.XScrlPos = (vdp->sdp.XScrlPos*vdp->sdp.UnitX/2)/vdp->sdp.UnitX;
4611   vdp->sdp.YScrlPos = (vdp->sdp.YScrlPos*vdp->sdp.UnitY/2)/vdp->sdp.UnitY;
4612 
4613   /*current scroll status*/
4614   vsb = GetSlateVScrollBar ((SlatE) vdp->panel);
4615   VCurPos=GetBarValue(vsb);
4616   hsb = GetSlateHScrollBar ((SlatE) vdp->panel);
4617   HCurPos=GetBarValue(hsb);
4618 
4619   /* update scroll values*/
4620   DOT_VScrlUpdate(vdp, vsb, VCurPos);
4621   DOT_HScrlUpdate(vdp, hsb, HCurPos);
4622 
4623   DOT_UpdateDataRects(data, rcP, vdp, TRUE);
4624 
4625   InsetRect(&rcP, -1, -1);
4626   InvalRect (&rcP);
4627   RestorePort (temport);
4628   Update();
4629   
4630 }
4631 
4632 /*________________________________________(DOT_EnlargeSizeProc)_____________
4633   Purpose : Reduce compression of main window display.
4634 
4635 ____________________________________________________________________*/
4636 static void DOT_EnlargeSizeProc (IteM i) 
4637 {
4638   WindoW    w, temport;
4639   RecT      rcP;
4640   DOTVibDataPtr vdp;
4641   DOTSelDataPtr  data;
4642   Int4     VCurPos, HCurPos;
4643   BaR      vsb, hsb;
4644 
4645   w = (WindoW)ParentWindow(i);
4646   temport = SavePort(w);
4647 
4648   vdp = (DOTVibDataPtr)GetObjectExtra (w);
4649   if (vdp==NULL) return;
4650 
4651   data=(DOTSelDataPtr)vdp->data;
4652 
4653   Select(vdp->panel);
4654   ObjectRect(vdp->panel, &rcP);
4655   if (vdp->comp >= 2)
4656     {
4657       vdp->comp/= 2;
4658     }
4659 
4660   DOT_SetCurrSeqlen(vdp);
4661   DOT_SetScrlVals (vdp);
4662   DOT_UpdateDataRects(data, rcP, vdp, TRUE);
4663 
4664   vdp->sdp.XScrlPos = (vdp->sdp.XScrlPos*vdp->sdp.UnitX*2)/vdp->sdp.UnitX;
4665   vdp->sdp.YScrlPos = (vdp->sdp.YScrlPos*vdp->sdp.UnitY*2)/vdp->sdp.UnitY;
4666 
4667   /*current scroll status*/
4668   vsb = GetSlateVScrollBar ((SlatE) vdp->panel);
4669   VCurPos=GetBarValue(vsb);
4670   hsb = GetSlateHScrollBar ((SlatE) vdp->panel);
4671   HCurPos=GetBarValue(hsb);
4672 
4673   /* update scroll values*/
4674   DOT_VScrlUpdate(vdp, vsb, VCurPos);
4675   DOT_HScrlUpdate(vdp, hsb, HCurPos);
4676 
4677   InsetRect(&rcP, -1, -1);
4678   InvalRect (&rcP);
4679   RestorePort (temport);
4680   Update();
4681   
4682 }
4683 
4684 static void DOT_ImageSizeHasChanged(DOTVibDataPtr vdp)
4685 {
4686   BaR      vsb, hsb;
4687   Int4     HCurPos, VCurPos;
4688 
4689   DOT_SetCurrSeqlen(vdp);
4690   DOT_SetScrlVals (vdp);
4691 
4692   /*current scroll status*/
4693   vsb = GetSlateVScrollBar ((SlatE) vdp->panel);
4694   VCurPos=GetBarValue(vsb);
4695   hsb = GetSlateHScrollBar ((SlatE) vdp->panel);
4696   HCurPos=GetBarValue(hsb);
4697 
4698   /* update scroll values*/
4699   DOT_VScrlUpdate(vdp, vsb, VCurPos);
4700   DOT_HScrlUpdate(vdp, hsb, HCurPos);
4701 
4702 }
4703 
4704 /*________________________________________(DOT_OriginalSizeProc)_____________
4705 
4706   Purpose : Resize the main window display to the original size.
4707 
4708 ____________________________________________________________________*/
4709 static void DOT_OriginalSizeProc (IteM i) 
4710 {
4711   WindoW    w, temport;
4712   RecT      rcP;
4713   DOTVibDataPtr vdp;
4714   DOTSelDataPtr  data;
4715 
4716   w = (WindoW)ParentWindow(i);
4717   temport = SavePort(w);
4718 
4719   vdp = (DOTVibDataPtr)GetObjectExtra (w);
4720   if (vdp==NULL) return;
4721 
4722   data=(DOTSelDataPtr)vdp->data;
4723 
4724   Select(vdp->panel);
4725   ObjectRect(vdp->panel, &rcP);
4726   
4727   vdp->comp = vdp->originalcomp;
4728   
4729   DOT_ImageSizeHasChanged(vdp);
4730   DOT_UpdateDataRects(data, rcP, vdp, TRUE);
4731 
4732 
4733   InsetRect(&rcP, -1, -1);
4734   InvalRect (&rcP);
4735   RestorePort (temport);
4736   Update();
4737   
4738 }
4739 
4740 /*_______________________________________________(DOT_GetInfoProc)___
4741 
4742   Purpose : 'About' information on software features.
4743 
4744 ____________________________________________________________________*/
4745 
4746 static void DOT_GetInfoProc (IteM i)
4747 
4748 {
4749   WindoW   w;
4750 
4751   w = FixedWindow(-50, -1, -1, -1, "Info", StdCloseWindowProc);
4752   StaticPrompt (w, "Dot plotter..", 0,  popupMenuHeight, programFont, 'l');
4753 
4754   RealizeWindow(w);
4755   Show (w);
4756 }
4757 
4758 /*_______________________________________________(DOT_FeatAnalysisProc)____
4759   
4760 
4761   Purpose : Bring up Feature analysis selection window.
4762 
4763 ____________________________________________________________________*/
4764 static void DOT_FeatAnalysisProc(ButtoN b)
4765 {
4766   WindoW  w;
4767   GrouP   g, g2;
4768 
4769 
4770   w = FixedWindow(-50, -1, -1, -1, "ACUTE", StdCloseWindowProc);
4771 
4772   g = HiddenGroup(w, 0, 2, NULL);
4773   g2 = HiddenGroup(g, 0, 2, NULL);
4774   RadioButton(g2, "Coils");
4775   RadioButton(g2, "SEG");
4776 
4777   RealizeWindow(w);
4778   Show (w);
4779 }
4780 
4781 
4782 /*_______________________________________________(DOT_GetValue)________
4783 
4784  Purpose: Get int value of input TexT
4785 
4786 _______________________________________________________________________*/
4787 extern Int4 DOT_GetValue (TexT t)
4788 {
4789   Char str[20];
4790   Int4 val;
4791 
4792   GetTitle (t,  str,  sizeof(str));
4793   if (StringHasNoText(str))
4794     {
4795       ErrPostEx (SEV_WARNING, 0, 0, "%s", "missing parameter(s)");
4796       return -1;
4797     }
4798 
4799   val=atoi(str);
4800 
4801   return val;
4802 }
4803 
4804 
4805 /*_______________________________________________(DOT_DoParams)___
4806 
4807   Purpose : Recalculate dot plot with new parameters.
4808 
4809 ____________________________________________________________________*/
4810 
4811 void DOT_DoParams(ButtoN b)
4812 {
4813   WindoW w;
4814   DOTparamsinfoPtr pip;
4815   DOTVibDataPtr       vdp;
4816   DOTMainDataPtr      mip;
4817 
4818   WatchCursor();
4819   w=(WindoW)ParentWindow(b);
4820   if (!(pip=(DOTparamsinfoPtr)GetObjectExtra(b))) return;
4821   if (!(vdp=(DOTVibDataPtr)GetObjectExtra(w))) return;
4822   mip=vdp->mip;
4823 
4824   DOT_FreeHitsArray(mip->hitlist, mip->index);
4825 
4826   mip->word_size = DOT_GetValue(pip->word_size);
4827   mip->tree_limit = DOT_GetValue(pip->tree_limit);
4828   mip->first_pass=TRUE;
4829   mip->cutoff_score=0;  
4830 
4831   if (pip) MemFree(pip);
4832 
4833   if (DOT_BuildHitList(mip, TRUE, TRUE)<0) 
4834     {
4835       Message(MSG_ERROR, "DOT- No hits");
4836       return; /* no hits */
4837     }
4838 
4839   DOT_UpdateMainPanel(vdp, TRUE);
4840   ArrowCursor();
4841   Remove(w);
4842 }
4843 
4844 void DOT_CancelParams(ButtoN b)
4845 {
4846 
4847   WindoW  w;
4848   DOTparamsinfoPtr pip;
4849 
4850   w=ParentWindow(b);
4851   pip=(DOTparamsinfoPtr)GetObjectExtra(b);
4852   if (pip) MemFree(pip);
4853   Remove(w);
4854 }
4855 
4856 
4857 void DOT_QuitProg(ButtoN b)
4858 {
4859 
4860   WindoW  w;
4861   DOTparamsinfoPtr pip;
4862   DOTVibDataPtr       vdp2;
4863 
4864   w=ParentWindow(b);
4865   pip=(DOTparamsinfoPtr)GetObjectExtra(b);
4866   vdp2=(DOTVibDataPtr)GetObjectExtra(w);
4867   if (vdp2->mip){
4868     DOT_FreeMainInfo(vdp2->mip);
4869     if (vdp2->mip) MemFree(vdp2->mip);
4870   }
4871   if (vdp2) MemFree(vdp2);
4872   if (pip) MemFree(pip);
4873   Remove(w);
4874   QuitProgram();
4875 }
4876 
4877 /*____________________________________________(DOT_StartDOTPLOT)_____________
4878 
4879 
4880   Purpose : Starts Dot Plot with user parameters.
4881 
4882 ____________________________________________________________________*/
4883 
4884 void DOT_StartDOTPLOT(ButtoN b)
4885 {
4886   WindoW w;
4887   DOTparamsinfoPtr pip;
4888   DOTVibDataPtr       vdp;
4889   DOTMainDataPtr      mip;
4890   BioseqPtr        qbsp, sbsp;
4891 
4892 
4893   WatchCursor();
4894   w=(WindoW)ParentWindow(b);
4895   pip=(DOTparamsinfoPtr)GetObjectExtra(b);
4896   vdp=(DOTVibDataPtr)GetObjectExtra(w);
4897   mip=(DOTMainDataPtr)MemNew(sizeof(DOTMainData));
4898 /*   DOT_FreeHitsArray(mip->hitlist, mip->index); */
4899 
4900   mip->q_start= DOT_GetValue(pip->xstart);
4901   mip->q_stop=DOT_GetValue(pip->xstop);
4902   mip->s_start=DOT_GetValue(pip->ystart);
4903   mip->s_stop=DOT_GetValue(pip->ystop);
4904   mip->qlen = (mip->q_stop-mip->q_start) + 1;
4905   mip->slen = (mip->s_stop-mip->s_start) + 1;
4906   mip->word_size = DOT_GetValue(pip->word_size);
4907   mip->tree_limit = DOT_GetValue(pip->tree_limit);
4908   mip->first_pass=TRUE;
4909   mip->cutoff_score=0; 
4910   if (pip) MemFree(pip);
4911 
4912   qbsp=mip->qbsp;
4913   sbsp=mip->sbsp;
4914   Remove(w);
4915 
4916   DOT_CreateAndStore(mip, qbsp, sbsp, mip->q_start, mip->q_stop, mip->s_start, mip->s_stop, mip->word_size, mip->tree_limit, FALSE);
4917 
4918 }
4919 
4920 
4921 
4922 void DOT_SetupParamsWindow(DOTVibDataPtr vdp, Boolean is_startup, Boolean is_nuc)
4923 {
4924   GrouP g, g1, g2,p1, p2;
4925   GrouP mainzoomg, zoomg1, zoomg2;
4926   ButtoN  b1, b2;
4927   DOTparamsinfoPtr pip;
4928   DOTMainDataPtr   mip;
4929   WindoW  w;
4930   Char    str1[20], str2[20], str3[20], str4[20];
4931 
4932 
4933   ArrowCursor();
4934 
4935   pip=(DOTparamsinfoPtr)MemNew(sizeof(DOTparamsinfo));
4936   mip=vdp->mip;
4937 
4938   w = FixedWindow(-50, -25, -1, -1, "Parameters", StdCloseWindowProc);
4939   SetObjectExtra(w, (Pointer)vdp, NULL);
4940 
4941   if (is_startup)
4942     {
4943       g=HiddenGroup(w, 1, 3, NULL);
4944       mainzoomg = NormalGroup(g, 1, 2, "Zoom Parameters", systemFont, NULL);
4945       sprintf(str1, "%d", mip->q_start);
4946       sprintf(str2, "%d", mip->s_start);
4947       sprintf(str3, "%d", mip->q_stop);
4948       sprintf(str4, "%d", mip->s_stop);
4949       zoomg1=HiddenGroup(mainzoomg, 3, 1, NULL);
4950       StaticPrompt(zoomg1, "x-axis:", 0, 0, systemFont, 'l');
4951       pip->xstart = DialogText(zoomg1, str1, 5, NULL);
4952       pip->xstop = DialogText(zoomg1, str3, 5, NULL);
4953       zoomg2=HiddenGroup(mainzoomg, 3, 1, NULL);
4954       StaticPrompt(zoomg2, "y-axis:", 0, 0, systemFont, 'l');
4955       pip->ystart = DialogText(zoomg2, str2, 5, NULL);
4956       pip->ystop = DialogText(zoomg2, str4, 5, NULL);
4957     }
4958   else
4959     g=HiddenGroup(w, 1, 2, NULL);
4960 
4961   g1 = NormalGroup(g, 1, 2, "Parameters", systemFont, NULL);
4962   sprintf(str1, "%d", mip->word_size);
4963   sprintf(str2, "%d", mip->tree_limit);
4964   if (is_nuc)
4965     sprintf(str3, "(4 - 11):", NULL);
4966   else
4967     sprintf(str3, "(1, 2 or 3):", NULL);
4968 
4969   p1=HiddenGroup(g1, 3, 1, NULL);
4970   StaticPrompt(p1, "Word size ", 0, 0, systemFont, 'l');
4971   StaticPrompt(p1, str3, 0, 0, systemFont, 'l');
4972   pip->word_size = DialogText(p1, str1, 5, NULL);
4973 
4974   p2=HiddenGroup(g1, 2, 1, NULL);
4975   StaticPrompt(p2, "Max number of hits:", 0, 0, systemFont, 'l');
4976   pip->tree_limit = DialogText(p2, str2, 5, NULL);
4977 
4978   if (!is_startup)
4979     {
4980       g2=HiddenGroup(g, 2, 1, NULL);
4981       b1 =PushButton(g2, "Accept", DOT_DoParams);
4982       b2 =PushButton(g2, "Cancel", DOT_CancelParams);
4983       SetObjectExtra(b1, (Pointer)pip, StdCleanupExtraProc);
4984       SetObjectExtra(b2, (Pointer)pip, StdCleanupExtraProc);
4985     }
4986   else
4987     {
4988       g2=HiddenGroup(g, 2, 1, NULL);
4989       b1 =PushButton(g2, "Accept", DOT_StartDOTPLOT);
4990       b2 =PushButton(g2, "Cancel", DOT_QuitProg);
4991       SetObjectExtra(b1, (Pointer)pip, StdCleanupExtraProc);
4992       SetObjectExtra(b2, (Pointer)pip, StdCleanupExtraProc);
4993     }
4994   
4995   Show(w);
4996 
4997 }
4998 
4999 
5000 static void DOT_ParametersProc (IteM i)
5001 {
5002   DOTVibDataPtr          vdp;
5003   WindoW              temport, w;
5004   RecT                rc;
5005   
5006   w= (WindoW)ParentWindow(i);
5007   temport=SavePort(w);
5008   vdp=(DOTVibDataPtr)GetObjectExtra(w);
5009 
5010   if (vdp==NULL) return;
5011 
5012   DOT_SetupParamsWindow(vdp, FALSE, FALSE);
5013 
5014   Select(vdp->panel);
5015   ObjectRect(vdp->panel, &rc);
5016    
5017   InsetRect(&rc, -1, -1);
5018   InvalRect (&rc);
5019   RestorePort (temport);
5020   Update();
5021 
5022 }
5023 
5024 
5025 /*_________________________________________(DOT_GetNthSeqFromAlign)_____
5026 
5027   Purpose : Fill nucleotide sequence buffers.
5028 
5029 ____________________________________________________________________*/
5030 
5031 static Uint1Ptr DOT_GetNthSeqFromAlign (SeqAlignPtr sap, Int4 n)
5032 {
5033   BioseqPtr        bsp=NULL;
5034   SeqIdPtr         sip=NULL;
5035   SeqPortPtr       spp;
5036   Uint1Ptr         seq, temp_seq;
5037   Uint1            strand;
5038   Int4             start=0, stop=0;
5039   Int4             len, buf_len;
5040   Int2             ctr, i;    
5041   Uint1Ptr         buffer;
5042   
5043   sip=AlnMgr2GetNthSeqIdPtr(sap, n);
5044   bsp=BioseqLockById(sip); 
5045   strand=AlnMgr2GetNthStrand(sap, n);
5046   AlnMgr2GetNthSeqRangeInSA(sap, n, &start, &stop);
5047   len=AlnMgr2GetAlnLength(sap, FALSE);
5048  /* initialize buffers */
5049   buffer=(Uint1Ptr) MemNew (sizeof(Uint1)*101); 
5050   MemSet((Pointer)buffer, '\0', sizeof(Char)*101);
5051   temp_seq = NULL;
5052   if (!(seq = (Uint1Ptr) MemNew (sizeof(Uint1)*(len)))) goto error;
5053   if (ISA_aa (bsp->mol)) 
5054     {
5055       spp = SeqPortNew (bsp, start, stop, strand, Seq_code_ncbi2na); 
5056     }
5057   else if (ISA_na(bsp->mol)) 
5058     {
5059       spp = SeqPortNew (bsp, start, stop, strand, Seq_code_ncbistdaa); 
5060     }
5061   if (spp == NULL)
5062     {
5063       ErrPostEx (SEV_ERROR, 0, 0, "%s", "DOT- Failed on SeqPortNew");
5064       goto error;
5065     }
5066   temp_seq =  seq;
5067   do 
5068     {
5069       ctr = SeqPortRead(spp, buffer, 100);
5070       
5071       if (ctr > 0) 
5072         {  
5073           i = 0;
5074           buf_len = ctr;
5075           while (buf_len > 0)
5076             {
5077               *temp_seq = (Uint1)buffer[i];
5078               temp_seq++;
5079               i++;  
5080               buf_len--;
5081             }
5082         }
5083     } while (ctr != SEQPORT_EOF * -1);
5084   SeqPortFree(spp);
5085   if (buffer) MemFree(buffer);
5086   BioseqUnlock(bsp);
5087   return seq;
5088  error:
5089   BioseqUnlock(bsp);
5090   return NULL;
5091 }
5092 /*_______________________________________________(DOT_DoZoom)___
5093 
5094   Purpose : Zoom into a specific region of sequence.
5095 
5096 ____________________________________________________________________*/
5097 
5098 void DOT_DoZoom(ButtoN b)
5099 {
5100   WindoW w;
5101   DOTparamsinfoPtr zip;
5102   DOTVibDataPtr     vdp;
5103   DOTSelDataPtr  data;
5104   DOTMainDataPtr mip;
5105   Int4           viewersize, newLen;
5106   RecT           rc;
5107 
5108 
5109   w=(WindoW)ParentWindow(b);
5110   if (!(zip=(DOTparamsinfoPtr)GetObjectExtra(b))) return;
5111   if (!(vdp=(DOTVibDataPtr)GetObjectExtra(w))) return;
5112   mip=vdp->mip;
5113   data=vdp->data;
5114   Remove(w);
5115 
5116   DOT_FreeHitsArray(mip->hitlist, mip->index);
5117 
5118 
5119   mip->q_start= DOT_GetValue(zip->xstart);
5120   mip->q_stop=DOT_GetValue(zip->xstop);
5121   mip->s_start=DOT_GetValue(zip->ystart);
5122   mip->s_stop=DOT_GetValue(zip->ystop);
5123   mip->qlen=mip->q_stop-mip->q_start + 1;
5124   mip->slen=mip->s_stop-mip->s_start + 1;
5125   mip->first_pass = TRUE;
5126   mip->cutoff_score=0;  
5127 
5128   DOT_GetSeqs(mip, TRUE);
5129   if (DOT_BuildHitList(mip, TRUE, TRUE)<0) 
5130     {
5131       Message(MSG_ERROR, "DOT- No hits");
5132       return; /* no hits */
5133     } 
5134  
5135   ObjectRect(vdp->panel, &rc);
5136   viewersize=MIN(rc.right-rc.left,rc.bottom-rc.top)-vdp->HORZ_MARGIN;
5137   newLen=MAX(mip->qlen, mip->slen);
5138   vdp->comp=DOT_Compression(newLen, viewersize);
5139 
5140   DOT_ImageSizeHasChanged(vdp);
5141 
5142   DOT_UpdateMainPanel(vdp, TRUE);
5143 
5144   if (zip) MemFree(zip);
5145   
5146 }
5147 
5148 
5149 
5150 static void DOT_CancelZoom (ButtoN b)
5151 {
5152   WindoW  w;
5153   DOTparamsinfoPtr zip;
5154 
5155   w=ParentWindow(b);
5156   zip=(DOTparamsinfoPtr)GetObjectExtra(b);
5157   if (zip) MemFree(zip);
5158   Remove(w);
5159 }
5160 
5161 
5162 void DOT_SetupZoomWindow(DOTVibDataPtr vdp)
5163 {
5164   GrouP          g, zoomg, bottomg, maingroup;
5165   ButtoN         b1, b2;
5166   DOTparamsinfoPtr zip;
5167   DOTMainDataPtr   mip;
5168   WindoW         w;
5169   Char           str1[20], str2[20], str3[20], str4[20];
5170 
5171   if (!(zip=(DOTparamsinfoPtr)MemNew(sizeof(DOTparamsinfo)))) return;
5172   mip=vdp->mip;
5173   w = FixedWindow(-50, -25, -1, -1, "Zoom", StdCloseWindowProc);
5174   SetObjectExtra(w, (Pointer)vdp, NULL);
5175   maingroup=HiddenGroup(w, -1, 2, NULL);
5176   g = NormalGroup(maingroup, 1, 2, "Zoom Parameters", systemFont, NULL);
5177   sprintf(str1, "%d", mip->q_start);
5178   sprintf(str2, "%d", mip->s_start);
5179   sprintf(str3, "%d", mip->q_stop);
5180   sprintf(str4, "%d", mip->s_stop);
5181   zoomg=HiddenGroup(g, 3, 2, NULL);
5182   StaticPrompt(zoomg, "x-axis:", 0, 0, systemFont, 'l');
5183   zip->xstart = DialogText(zoomg, str1, 5, NULL);
5184   zip->xstop = DialogText(zoomg, str3, 5, NULL);
5185   StaticPrompt(zoomg, "y-axis:", 0, 0, systemFont, 'l');
5186   zip->ystart = DialogText(zoomg, str2, 5, NULL);
5187   zip->ystop = DialogText(zoomg, str4, 5, NULL);
5188 
5189   bottomg=HiddenGroup(maingroup, 2, 1, NULL);
5190   b1 =PushButton (bottomg, "Accept", DOT_DoZoom);
5191   b2 =PushButton(bottomg, "Cancel", DOT_CancelZoom);
5192   SetObjectExtra(b1, (Pointer)zip, StdCleanupExtraProc);
5193   SetObjectExtra(b2, (Pointer)zip, StdCleanupExtraProc);
5194 
5195   Show(w);
5196 }
5197 
5198 static void DOT_ZoomProc (IteM i)
5199 {
5200   DOTVibDataPtr          vdp;
5201   WindoW              temport, w;
5202   
5203   w= (WindoW)ParentWindow(i);
5204   temport=SavePort(w);
5205   vdp=(DOTVibDataPtr)GetObjectExtra(w);
5206   if (vdp==NULL) return;
5207 
5208   DOT_SetupZoomWindow(vdp); 
5209   
5210 }
5211 
5212 
5213 /*_______________________________________________(DOT_DoDisplayOpts)___
5214 
5215   Purpose : Update Display
5216 
5217 ____________________________________________________________________*/
5218 
5219 
5220 static void DOT_DisplayOptsProc(ChoicE i)
5221 
5222 {
5223   DOTVibDataPtr          vdp;
5224   WindoW              w;
5225   Int4                value;
5226   
5227 
5228   w=(WindoW)ParentWindow(i);
5229   vdp=(DOTVibDataPtr)GetObjectExtra(w);
5230   
5231   value=GetValue(i);
5232   
5233   if (value==1)
5234     {
5235       vdp->showDotPlot=TRUE;
5236       vdp->showALIGN=FALSE;
5237     }
5238   else if (value==2)
5239     {
5240       vdp->showDotPlot=TRUE;
5241       vdp->showALIGN=TRUE;
5242     }
5243   else if (value==3)
5244     {
5245       vdp->showDotPlot=FALSE;
5246       vdp->showALIGN=TRUE;
5247     }
5248 
5249   DOT_UpdateMainPanel(vdp, TRUE);
5250   
5251 }
5252 
5253 
5254 /*____________________________________________(DOT_AlignInfoNew)_____________
5255 
5256 
5257   Purpose : Initialize DOTAlignInfoPtr.
5258 
5259 ____________________________________________________________________*/
5260 extern DOTAlignInfoPtr DOT_AlignInfoNew (void)
5261 {
5262   DOTAlignInfoPtr alp;
5263   
5264   alp=(DOTAlignInfoPtr)MemNew(sizeof(DOTAlignInfo));
5265   alp->VERT_MARGIN=50;
5266   alp->HORZ_MARGIN=80;
5267   alp->do_scale=TRUE;
5268   alp->showLabels=FALSE;
5269   alp->Fh=FontHeight();
5270   return alp;
5271 }
5272 /*___________________________(AlnMgr2GetNextLine)_______
5273 
5274 
5275   Purpose : Get starts and stops for a seq_align.
5276 
5277 ____________________________________________________________________*/
5278 static Boolean AlnMgr2GetNextLine(SeqAlignPtr sap, AlnMsg2Ptr amp1, AlnMsg2Ptr amp2, Int4Ptr x1, Int4Ptr y1, Int4Ptr x2, Int4Ptr y2, Int4Ptr n) 
5279 { 
5280   Boolean  retval; 
5281   
5282   if (sap == NULL || amp1 == NULL || amp2 == NULL || x1 == NULL || y1 == NULL || x2 == NULL || y2 == NULL ||n == NULL) 
5283     return FALSE;
5284   amp1->row_num = 1; 
5285   retval = AlnMgr2GetNextAlnBit(sap, amp1);
5286   if (retval == FALSE) 
5287     return FALSE; 
5288   if (amp1->type == AM_SEQ) 
5289     { 
5290       *x1 = amp1->from_row; 
5291       *x2 = amp1->to_row; 
5292     } else 
5293       { 
5294         if (*x2 == 0) 
5295           AlnMgr2GetNthSeqRangeInSA(sap, 1, x2, NULL); 
5296         *x1 = *x2;
5297       } 
5298   amp2->row_num = 2;
5299   retval = AlnMgr2GetNextAlnBit(sap, amp2);
5300   if (retval == FALSE) 
5301     return FALSE; 
5302   if (amp2->type == AM_SEQ) 
5303     { 
5304       *y1 = amp2->from_row;
5305       *y2 = amp2->to_row; 
5306     } else 
5307       { 
5308         if (*y2 == 0) 
5309           AlnMgr2GetNthSeqRangeInSA(sap, 2, y2, NULL); 
5310         *y1 = *y2;
5311       } 
5312   *n++;
5313   return TRUE; 
5314 } 
5315 
5316 /*____________________________________________(DOT_GetAlign)___________
5317 
5318 
5319   Purpose : Get seq_align coordinates, store as DOTAlnList array.
5320 
5321 ____________________________________________________________________*/
5322 static Boolean DOT_GetAlign (DOTAlignInfoPtr alp)
5323 { 
5324   AlnMsg2Ptr    amp1, amp2;
5325   BioseqPtr    bsp1, bsp2;
5326   SeqAlignPtr  sap=NULL, salp=NULL, sap_tmp=NULL;
5327   DOTAlnPtr    Aln;
5328   Boolean      saved=FALSE;
5329   Int4         x1, y1, x2, y2, numlines=0, n=0, i=0;
5330   Int4         xlen=0, ylen=0;
5331   Uint1         q_strand, s_strand;
5332   
5333    if (alp==NULL || alp->sap==NULL)
5334   {
5335     ArrowCursor();
5336     return(FALSE);
5337   }
5338   sap=alp->sap;
5339 
5340  if (sap->segtype==SAS_DISC)
5341     { 
5342       salp=(SeqAlignPtr)sap->segs;      
5343     } 
5344   else 
5345     {
5346       salp=sap; 
5347     } 
5348   alp->sip=AlnMgr2GetNthSeqIdPtr(salp, 1);
5349   alp->sip->next=AlnMgr2GetNthSeqIdPtr(salp, 2);
5350   alp->title = NULL;
5351   sap_tmp=salp;
5352   while (sap_tmp){
5353     numlines +=AlnMgr2GetNumSegs(sap_tmp);
5354     sap_tmp=sap_tmp->next;
5355   }
5356   amp1 = AlnMsgNew2(); 
5357   amp2 = AlnMsgNew2();
5358   amp1->from_aln = amp2->from_aln = 0;
5359   amp1->to_aln = amp2->to_aln = -1;  
5360   amp1->row_num = 1;
5361   amp2->row_num = 2;
5362   alp->Alnlist=(DOTAlnPtr PNTR) MemNew(sizeof(DOTAlnPtr)*numlines);
5363   n = x1 = x2 = y1 = y2 = i =xlen=ylen=0; 
5364   while (salp)
5365     {
5366       q_strand = AlnMgr2GetNthStrand(salp, 1);
5367       s_strand = AlnMgr2GetNthStrand(salp, 2);
5368       while (AlnMgr2GetNextAlnBit(salp, amp1) && AlnMgr2GetNextAlnBit(salp, amp2))
5369         { 
5370           if (amp1->type == AM_SEQ && amp2->type == AM_SEQ){
5371             saved=TRUE;
5372             Aln=(DOTAlnPtr)MemNew(sizeof(DOTAln));
5373             Aln->sap=salp;
5374             
5375             if (q_strand == Seq_strand_minus){
5376               Aln->q_start = x2;
5377               Aln->q_stop = x1;
5378             }
5379             else {
5380               Aln->q_start=x1;
5381               Aln->q_stop=x2;
5382             }
5383             if (s_strand == Seq_strand_minus){
5384               Aln->s_start = y2;
5385               Aln->s_stop = y1;
5386             }
5387             else {
5388               Aln->s_start=y1;
5389               Aln->s_stop=y2;
5390             }
5391             Aln->primID=i+1;
5392             Aln->entityID=salp->idx.entityID;
5393             Aln->itemID=salp->idx.itemID;
5394             Aln->class=dotaln_GENERAL;
5395             alp->Alnlist[i]=Aln;
5396             i++;
5397           }
5398         }
5399       AlnMsgReNew2(amp1);
5400       AlnMsgReNew2(amp2);
5401       amp1->to_aln = amp2->to_aln = -1;
5402       salp=salp->next;
5403     }
5404   
5405   if (!saved)
5406     {
5407       ErrPostEx(SEV_ERROR, 0, 0, "no alignments found");
5408       return (FALSE);
5409     }
5410   alp->index=i;
5411   AlnMsgFree2(amp1);
5412   AlnMsgFree2(amp2);
5413 
5414   bsp1=BioseqLockById(alp->sip); 
5415   bsp2=BioseqLockById(alp->sip->next); 
5416   alp->xstart=0;
5417   alp->xlen=bsp1->length;  
5418   alp->ystart=0;
5419   alp->ylen=bsp2->length; 
5420   BioseqUnlock(bsp1);
5421   BioseqUnlock(bsp2);
5422   return (TRUE);
5423 } 
5424 
5425 /*___________________________(DOT_FillEachAlign)___________
5426 
5427 
5428   Purpose : Fill Align structure from SeqAlignPtr PNTR
5429 
5430 __________________________________________________________*/
5431 static DOTAlnPtr DOT_FillEachAlign(DOTAlnPtr aln_list, SeqAlignPtr PNTR saps, Int4Ptr start, Int4 numsaps, Int4 class)
5432 {
5433   Int4         i = 0;
5434   Int4         j = 0;
5435   AlnMsg2Ptr    amp1, amp2;
5436   DOTAlnPtr    Aln = NULL, Aln_head = NULL, aln_end = NULL, Aln_next = NULL;
5437   Uint1        q_strand, s_strand;
5438 
5439 
5440   amp1 = AlnMsgNew2(); 
5441   amp2 = AlnMsgNew2(); 
5442   amp1->from_aln = amp2->from_aln = 0;
5443   amp1->to_aln = amp2->to_aln = -1; 
5444   amp1->row_num = 1;
5445   amp2->row_num = 2;
5446   numsaps+=*start;
5447   if (aln_list){
5448     aln_end=aln_list;
5449     while (aln_end->next != NULL)
5450       aln_end=aln_end->next;
5451   }
5452 
5453   if (numsaps > 0)
5454     {
5455       for(i=*start; i<numsaps; i++){
5456         q_strand = AlnMgr2GetNthStrand(saps[i-*start], 1);
5457         s_strand = AlnMgr2GetNthStrand(saps[i-*start], 2);
5458         while(AlnMgr2GetNextAlnBit(saps[i-*start], amp1) && AlnMgr2GetNextAlnBit(saps[i-*start], amp2)) 
5459           { 
5460             if (amp1->type == AM_SEQ && amp2->type == AM_SEQ) {
5461               Aln=(DOTAlnPtr)MemNew(sizeof(DOTAln));
5462               Aln->sap=saps[i-*start];
5463               if (q_strand == Seq_strand_minus) {
5464                 Aln->q_start = amp1->to_row;
5465                 Aln->q_stop = amp1->from_row;
5466               }
5467               else {
5468                 Aln->q_start = amp1->from_row;
5469                 Aln->q_stop = amp1->to_row;
5470               }
5471               if (s_strand == Seq_strand_minus) {
5472                 Aln->s_start = amp2->to_row;
5473                 Aln->s_stop = amp2->from_row;
5474               }
5475               else {
5476                 Aln->s_start = amp2->from_row;
5477                 Aln->s_stop = amp2->to_row;
5478               }
5479               Aln->primID=j+1;
5480               Aln->entityID=saps[i-*start]->idx.entityID;
5481               Aln->itemID=saps[i-*start]->idx.itemID;
5482               Aln->class=class;
5483               if (Aln_head){
5484                 Aln_next->next=Aln;
5485                 Aln_next=Aln_next->next;
5486               }
5487               else {
5488                 Aln_head=Aln_next=Aln;
5489               }
5490               j++;
5491             }
5492           }
5493       
5494         AlnMsgReNew2(amp1);
5495         AlnMsgReNew2(amp2);
5496         amp1->row_num = 1;
5497         amp2->row_num = 2;
5498       }
5499     }
5500 
5501   AlnMsgFree2(amp1);
5502   AlnMsgFree2(amp2);
5503 
5504   *start+=j;
5505 
5506   if (aln_list)
5507     aln_end->next=Aln_head;
5508   else 
5509     aln_list=Aln_head;
5510 
5511   return aln_list;
5512 }
5513 /*____________________________________________(DOT_IndexAlnlist)___________
5514 
5515 
5516   Purpose : index linked list of alignment coordinates into an array
5517 
5518 ____________________________________________________________________*/
5519 static DOTAlnPtr PNTR DOT_IndexAlnlist(DOTAlnPtr aln_head, Int4Ptr index)
5520 {
5521   DOTAlnPtr PNTR Alnlist=NULL;
5522   Int4      i=0;
5523 
5524   if (!aln_head || !index)
5525     return NULL;
5526 
5527   if(!(Alnlist=(DOTAlnPtr PNTR) MemNew(sizeof(DOTAlnPtr)* (*index)))){
5528     return NULL;
5529   }
5530   if (*index == 0 && aln_head) {
5531     i = 0;
5532     while (aln_head) {
5533       Alnlist[i] = aln_head;
5534       aln_head = aln_head->next;
5535       i++;
5536     }
5537     *index = i;
5538     return Alnlist;
5539   }
5540 
5541   for (i=0; i<*index; i++){
5542     Alnlist[i]=aln_head;
5543     aln_head=aln_head->next;
5544   }
5545   return Alnlist;
5546 }
5547 /*____________________________________________(DOT_FillAlignInfoPointer)___________
5548 
5549 
5550   Purpose : Get seq_align coordinates, store as DOTAlnList array.
5551 
5552 ____________________________________________________________________*/
5553 extern Boolean DOT_FillAlignInfoPointer (DOTAlignInfoPtr alp)
5554 { 
5555   AlnMsg2Ptr    amp1, amp2;  
5556   DOTAlnPtr    PNTR Alnlist=NULL;
5557   DOTAlnPtr    aln_list=NULL;
5558   BioseqPtr    bsp1, bsp2;
5559   SeqAlignPtr  sap=NULL, salp=NULL, sap_tmp=NULL;
5560   Boolean      saved=FALSE;
5561   Int4         numsaps = 0, numlines = 0;
5562   Int4         i=0, n=0;
5563   Int4         xstart=0, xstop=0;
5564   Int4         ystart=0, ystop=0;
5565   Char         q_idbuf[42]={""}, s_idbuf[42]={""};
5566   AMAlignIndex2Ptr amaip=NULL;
5567   Int4         alncount=0;
5568 
5569   if (alp==NULL){
5570     ArrowCursor();
5571     return(FALSE);
5572   }
5573   sap=alp->sap;
5574   if (!sap) return FALSE;
5575   if (sap->saip != NULL && sap->saip->indextype == INDEX_PARENT){
5576     amaip=(AMAlignIndex2Ptr)sap->saip;
5577     if (!amaip) return FALSE;
5578     salp=(SeqAlignPtr)sap->segs;
5579   }
5580   else {
5581     amaip=NULL;
5582     salp=sap;
5583   } 
5584 
5585   n = AlnMgr2GetNumRows(salp);
5586   if (n <= 0){
5587     ArrowCursor();
5588        return(FALSE);
5589   }
5590   if (n > 2){
5591     ErrPostEx(SEV_ERROR, 0, 0, "alignment contains greater than two rows");
5592     SeqIdSetFree(alp->sip);
5593     ArrowCursor();
5594     return FALSE;
5595   }
5596   alp->sip=AlnMgr2GetNthSeqIdPtr(salp, 1);
5597   alp->sip->next=AlnMgr2GetNthSeqIdPtr(salp, 2);
5598   
5599   SeqIdWrite(alp->sip, q_idbuf,PRINTID_FASTA_SHORT, 41);
5600   SeqIdWrite(alp->sip->next, s_idbuf,PRINTID_FASTA_SHORT, 41);
5601   alp->name1=StringSave(q_idbuf);
5602   alp->name2=StringSave(s_idbuf);
5603   bsp1=BioseqLockById(alp->sip);
5604   bsp2=BioseqLockById(alp->sip->next);
5605 
5606   if (ISA_aa (bsp1->mol) && ISA_aa (bsp2->mol)) 
5607     {
5608       alp->is_na = FALSE;
5609     }
5610   else if (ISA_na(bsp1->mol) && ISA_na (bsp2->mol)) 
5611     {
5612       alp->is_na = TRUE;
5613       alp->matrix=(Int4Ptr PNTR)DOT_DNAScoringMatrix(-3, 1, 4);
5614     }
5615   else
5616     goto error;
5617 
5618    sap_tmp=salp;
5619    while (sap_tmp){
5620      sap_tmp=sap_tmp->next;
5621      numsaps++;
5622    }
5623 
5624   amp1 = AlnMsgNew2(); 
5625   amp2 = AlnMsgNew2(); 
5626   amp1->to_aln = amp2->to_aln = -1; 
5627   if (amaip){
5628     aln_list = DOT_FillEachAlign(aln_list, amaip->saps, &alncount, numsaps,  1);
5629     saved=TRUE;
5630   }
5631   else {
5632     aln_list = DOT_FillEachAlign(aln_list, &salp, &alncount, numsaps, 1);
5633     saved=TRUE;
5634   }
5635 
5636   if (!saved)
5637     {
5638        ErrPostEx(SEV_WARNING, 0, 0, "Invalid SeqAlign format");
5639        return (FALSE);
5640   }
5641   numlines = alncount;
5642   Alnlist = DOT_IndexAlnlist(aln_list, &numlines);
5643   if (!Alnlist) goto error;
5644   alp->Alnlist=Alnlist;
5645   AlnMgr2GetNthSeqRangeInSA(salp, 1, &xstart, &xstop);
5646   AlnMgr2GetNthSeqRangeInSA(salp, 2, &ystart, &ystop);
5647   alp->xstart=xstart;
5648   alp->xlen=xstop-xstart+1;
5649   alp->ystart=ystart;
5650   alp->ylen=ystop-ystart+1;
5651   alp->index=numlines;
5652 
5653   ArrowCursor();
5654   BioseqUnlock(bsp1);
5655   BioseqUnlock(bsp2);
5656   return TRUE;
5657  error:
5658   BioseqUnlock(bsp1);
5659   BioseqUnlock(bsp2);
5660   return FALSE;
5661 }
5662 
5663 /*____________________________________________(DOT_FillAlignInfoPointer)___________
5664 
5665 
5666   Purpose : Get seq_align coordinates, store as DOTAlnList array.
5667 
5668 ____________________________________________________________________*/
5669 extern Boolean DOT_Prob_FillAlignInfoPointer (DOTAlignInfoPtr alp)
5670 { 
5671   AlnMsg2Ptr    amp1, amp2;  
5672   DOTAlnPtr    PNTR Alnlist=NULL;
5673   DOTAlnPtr    aln_list=NULL;
5674   BioseqPtr    bsp1, bsp2;
5675   SeqAlignPtr  sap=NULL, salp=NULL, sap_tmp=NULL;
5676   Boolean      saved=FALSE;
5677   Int4         numsaps = 0, numlines = 0;
5678   Int4         i=0, n=0;
5679   Int4         xstart=0, xstop=0;
5680   Int4         ystart=0, ystop=0;
5681   Char         q_idbuf[42]={""}, s_idbuf[42]={""};
5682   AMAlignIndex2Ptr amaip=NULL;
5683   Int4         alncount=0;
5684 
5685   if (alp==NULL){
5686     ArrowCursor();
5687     return(FALSE);
5688   }
5689   sap=alp->sap;
5690   if (!sap) return FALSE;
5691   
5692   if (sap->segtype==SAS_DISC){  
5693     salp=(SeqAlignPtr)sap->segs;  
5694   }  
5695   else { 
5696     salp=sap; 
5697   } 
5698   if (sap->saip == NULL)
5699     AlnMgr2IndexLite(sap);
5700   amaip = (AMAlignIndex2Ptr)sap->saip;
5701   
5702   n = AlnMgr2GetNumRows(salp);
5703   if (n <= 0){
5704     ArrowCursor();
5705        return(FALSE);
5706   }
5707   if (n > 2){
5708     ErrPostEx(SEV_ERROR, 0, 0, "alignment contains greater than two rows");
5709     SeqIdSetFree(alp->sip);
5710     ArrowCursor();
5711     return FALSE;
5712   }
5713   alp->sip=AlnMgr2GetNthSeqIdPtr(amaip->saps[0], 1);
5714   alp->sip->next=AlnMgr2GetNthSeqIdPtr(amaip->saps[0], 2);
5715   
5716   SeqIdWrite(alp->sip, q_idbuf,PRINTID_FASTA_SHORT, 41);
5717   SeqIdWrite(alp->sip->next, s_idbuf,PRINTID_FASTA_SHORT, 41);
5718   alp->name1=StringSave(q_idbuf);
5719   alp->name2=StringSave(s_idbuf);
5720   bsp1=BioseqLockById(alp->sip);
5721   bsp2=BioseqLockById(alp->sip->next);
5722   if (bsp2 == NULL){
5723     if (bsp1 != NULL)
5724       BioseqUnlock(bsp1);
5725   }
5726   if (ISA_aa (bsp1->mol) && ISA_aa (bsp2->mol)) 
5727     {
5728       alp->is_na = FALSE;
5729     }
5730   else if (ISA_na(bsp1->mol) && ISA_na (bsp2->mol)) 
5731     {
5732       alp->is_na = TRUE;
5733       alp->matrix=(Int4Ptr PNTR)DOT_DNAScoringMatrix(-3, 1, 4);
5734     }
5735   else
5736     goto error;
5737 
5738   amp1 = AlnMsgNew2(); 
5739   amp2 = AlnMsgNew2(); 
5740   amp1->to_aln = amp2->to_aln = -1; 
5741   if (amaip){
5742     aln_list = DOT_FillEachAlign(aln_list, amaip->saps, &alncount, amaip->numsaps,  1);
5743     saved=TRUE;
5744   }
5745 
5746   if (!saved)
5747     {
5748        ErrPostEx(SEV_WARNING, 0, 0, "no alignments saved");
5749        return (FALSE);
5750   }
5751   numlines = alncount;
5752   Alnlist = DOT_IndexAlnlist(aln_list, &numlines);
5753   if (!Alnlist) goto error;
5754   alp->Alnlist=Alnlist;
5755   alp->index=numlines;
5756 
5757   if (sap->segtype == SAS_DISC){
5758     alp->xstart = 1;
5759     alp->xlen = bsp1->length;
5760     alp->ystart = 1;
5761     alp->ylen = bsp2->length;
5762   }
5763   else {
5764     AlnMgr2GetNthSeqRangeInSA(salp, 1, &xstart, &xstop);
5765     AlnMgr2GetNthSeqRangeInSA(salp, 2, &ystart, &ystop);
5766     alp->xstart=xstart;
5767     alp->xlen=xstop-xstart+1;
5768     alp->ystart=ystart;
5769     alp->ylen=ystop-ystart+1;
5770   }
5771 
5772   ArrowCursor();
5773   BioseqUnlock(bsp1);
5774   BioseqUnlock(bsp2);
5775   return TRUE;
5776  error:
5777   BioseqUnlock(bsp1);
5778   BioseqUnlock(bsp2);
5779   return FALSE;
5780 }
5781 
5782 static SeqIdPtr DOT_GetNthSeqIdFromScp(SCP_ResultPtr scp, Int2 n)
5783 {
5784   SeqAlignPtr PNTR saps;
5785 
5786   
5787   if (scp->saps != NULL)
5788     saps=scp->saps;
5789   else if (scp->large_outliers !=NULL)
5790     saps=scp->large_outliers;
5791   else if (scp->small_outliers !=NULL)
5792     saps=scp->small_outliers;
5793   else
5794     return NULL;
5795 
5796   return(AlnMgr2GetNthSeqIdPtr(saps[0], n));  
5797 
5798 }
5799 
5800 
5801 /*____________________________________________(DOT_FillFromScp)___________
5802 
5803 
5804   Purpose : Get seq_align coordinates, store as DOTAlnList array.
5805 
5806 ____________________________________________________________________*/
5807 static Boolean DOT_FillFromScp (DOTAlignInfoPtr alp, SCP_ResultPtr scp)
5808 { 
5809   BioseqPtr    bsp1=NULL, bsp2=NULL;
5810   DOTAlnPtr    PNTR Alnlist=NULL;
5811   DOTAlnPtr    aln_list =NULL;
5812   Int4         start=0;
5813   Boolean      saved=FALSE;
5814   Char         q_idbuf[42]={""}, s_idbuf[42]={""};
5815 
5816   if (alp==NULL)
5817   {
5818     ArrowCursor();
5819     return(FALSE);
5820   }
5821   if (scp->saps == NULL && scp->small_outliers ==NULL && scp->large_outliers==NULL) return (FALSE);
5822 
5823   alp->sip = DOT_GetNthSeqIdFromScp(scp, 1);
5824   alp->sip->next = DOT_GetNthSeqIdFromScp(scp, 2);
5825   SeqIdWrite(alp->sip, q_idbuf,PRINTID_FASTA_SHORT, 41);
5826   SeqIdWrite(alp->sip->next, s_idbuf,PRINTID_FASTA_SHORT, 41);
5827   alp->name1=StringSave(q_idbuf);
5828   alp->name2=StringSave(s_idbuf);
5829   bsp1=BioseqLockById(alp->sip);
5830   bsp2=BioseqLockById(alp->sip->next);
5831 
5832   if (bsp2 == NULL){
5833     if (bsp1 != NULL)
5834       BioseqUnlock(bsp1);
5835   }
5836 
5837   if (ISA_aa (bsp1->mol) && ISA_aa (bsp2->mol)) 
5838     {
5839       alp->is_na = FALSE;
5840     }
5841   else if (ISA_na(bsp1->mol) && ISA_na (bsp2->mol)) 
5842     {
5843       alp->is_na = TRUE;
5844       alp->matrix=(Int4Ptr PNTR)DOT_DNAScoringMatrix(-3, 1, 4);
5845     }
5846   else
5847     goto error;
5848 
5849   if (scp->saps){
5850     aln_list = DOT_FillEachAlign(aln_list, scp->saps, &start, scp->numsaps, 1);
5851     saved=TRUE;
5852   }
5853   if (scp->large_outliers){
5854 /*     start= scp->numsaps; */
5855     aln_list = DOT_FillEachAlign(aln_list, scp->large_outliers, &start, scp->numlarge_outliers, 2);
5856     saved=TRUE;
5857   }
5858   if (scp->small_outliers){
5859 /*     start= scp->numsaps+scp->numlarge_outliers; */
5860     aln_list = DOT_FillEachAlign(aln_list, scp->small_outliers, &start, scp->numsmall_outliers, 3);
5861     saved=TRUE;
5862   }
5863   if (!saved)
5864     {
5865       ErrPostEx(SEV_WARNING, 0, 0, "no alignments saved");
5866       goto error;
5867     }
5868   Alnlist = DOT_IndexAlnlist(aln_list, &start);
5869   if (!Alnlist) goto error;
5870   alp->Alnlist=Alnlist;
5871   alp->xstart=1;
5872   alp->xlen=scp->len1;
5873   alp->ystart=1;
5874   alp->ylen=scp->len2;
5875   alp->index=start;
5876    ArrowCursor();
5877    BioseqUnlock(bsp1);
5878    BioseqUnlock(bsp2);
5879    return TRUE;
5880  error:
5881    BioseqUnlock(bsp1);
5882    BioseqUnlock(bsp2);
5883    return (FALSE);
5884 } 
5885 /*_______________________________________________(DOT_DoBlast)___
5886 
5887   Purpose : Calls Blast2Seq.
5888 
5889 ____________________________________________________________________*/
5890 
5891 static FloatHi DOT_get_eval(Int4 exp)
5892 {
5893   FloatHi eval;
5894   Int4 i;
5895 
5896   eval = 1;
5897   for (i=1; i<=exp; i++)
5898   {
5899      eval = eval/10;
5900   }
5901   return eval;
5902 }
5903 
5904 static void DOT_DoBlast (ButtoN b)
5905 {
5906   DOTVibDataPtr       vdp;
5907   WindoW              w;
5908   DOTblastinfoPtr     bip;
5909   BioseqPtr           bsp1, bsp2;
5910   Int2                i;
5911   Int2                progval;
5912   Uint2               entityID=0;
5913   CharPtr             text=NULL;
5914   Boolean             is_local;
5915   Char                eval[11]={""};
5916   Char                str[20]={""};
5917   SCP_ResultPtr       scp=NULL;
5918   DOTMainDataPtr      mip=NULL;
5919 
5920 
5921   WatchCursor();
5922   w = (WindoW)ParentWindow(b);
5923   vdp = (DOTVibDataPtr)GetObjectExtra(w);
5924   if (vdp == NULL)  goto end;
5925   mip = vdp->mip;
5926   if (mip == NULL) goto end;
5927 
5928   Remove(w);
5929 
5930   bip = (DOTblastinfoPtr)GetObjectExtra(b);
5931   if (bip == NULL || bip->bsp1 == NULL || bip->bsp2 == NULL)
5932     goto end;
5933   bsp1 = bip->bsp1;
5934   bsp2 = bip->bsp2;
5935 
5936   progval = GetValue (bip->progname);
5937   if (progval == 1) 
5938     StringCpy(str, "blastn");
5939   else 
5940     StringCpy(str, "blastp");
5941 
5942   i = GetValue(bip->localorglobal);
5943   if (i == 1)
5944     is_local = TRUE;
5945   else
5946     is_local = FALSE;
5947 
5948    if (vdp->alp){ /* previous alignment*/
5949      vdp->alp->pict = NULL;
5950      DOT_ExitAlign(vdp->alp);
5951      vdp->showALIGN = FALSE;
5952    }
5953    
5954    scp = SCP_CompareOrderOrganizeBioseqs(bsp1, bsp2, mip->qslp, mip->sslp, str, mip->word_size, mip->tree_limit);
5955    Remove(w);
5956    vdp->showALIGN=TRUE;
5957    SetValue(vdp->displayOpts2, 2);
5958    vdp->alp=DOT_AlignInfoNew();
5959    vdp->alp->sap=NULL;
5960    vdp->alp->entityID=scp->saps[0]->idx.entityID;
5961    vdp->alp->itemID=scp->saps[0]->idx.itemID;
5962    if (!DOT_FillFromScp(vdp->alp, scp))
5963      {
5964        vdp->alp->pict=NULL;
5965        DOT_ExitAlign(vdp->alp);
5966        vdp->showALIGN=FALSE;
5967      }
5968 
5969    DOT_UpdateMainPanel(vdp, TRUE);
5970    end:
5971    if (text) MemFree(text);
5972    ArrowCursor();
5973    return;
5974 }
5975 
5976 
5977 static void DOT_CancelBlast (ButtoN b)
5978 {
5979   WindoW  w;
5980   DOTblastinfoPtr bip;
5981 
5982   w=ParentWindow(b);
5983   bip=(DOTblastinfoPtr)GetObjectExtra(b);
5984   if (bip) MemFree(bip);
5985   Remove(w);
5986 }
5987 
5988 
5989 void DOT_SetupBlastWindow(DOTVibDataPtr vdp)
5990 {
5991    DOTblastinfoPtr   bip;
5992    DOTMainDataPtr    mip;
5993    ButtoN            b;
5994    ButtoN            b1;
5995    GrouP             maingroup, topg, localg, eANDwg;
5996    GrouP             submitg, blastg, bottomg, g3;
5997    Char              title[255]={""};
5998    WindoW            w;
5999    
6000 
6001 
6002    if (!(bip = (DOTblastinfoPtr)MemNew(sizeof(DOTblastinfo)))) return;
6003    mip=vdp->mip;
6004 
6005    bip->bsp1 = mip->qbsp;
6006    bip->bsp2 = mip->sbsp;
6007    StringCat(title, mip->qname);
6008    StringCat(title, " vs. ");
6009    StringCat(title, mip->sname);
6010    w = FixedWindow(-50, -25, -1, -1, title, StdCloseWindowProc);
6011    SetObjectExtra(w, vdp, NULL);
6012 
6013    maingroup = HiddenGroup(w, 1, 4, NULL);  
6014    StaticPrompt(maingroup, "Blast2Seqs Options ..", 0, popupMenuHeight, systemFont, 'l');
6015    topg = HiddenGroup (maingroup, -1, 2, NULL);
6016    blastg = NormalGroup(topg, 1,1, "Blast Program",  systemFont,NULL);
6017    bip->progname = HiddenGroup(blastg, 5, 0, NULL);
6018    RadioButton(bip->progname, "blastn");
6019    RadioButton(bip->progname, "blastp");
6020 /*    RadioButton(bip->progname, "blastx"); */
6021 /*    RadioButton(bip->progname, "tblastn"); */
6022 /*    RadioButton(bip->progname, "tblastx"); */
6023    SetValue(bip->progname, 1);
6024 
6025    /*
6026    globalg = NormalGroup(topg,1, 1, "Alignment Type",  systemFont,NULL);
6027    bip->localorglobal = HiddenGroup(globalg, 2, 1, NULL);
6028    RadioButton(bip->localorglobal, "Local");
6029    RadioButton(bip->localorglobal, "Global");
6030    SetValue(bip->localorglobal, 1);
6031 
6032    bottomg=HiddenGroup(maingroup, 1, 2, NULL);
6033    localg = NormalGroup(bottomg, 1, 3, "Local Alignment Options", systemFont, NULL);
6034    g1 = NormalGroup(localg, 1,1, "",  systemFont,NULL);
6035    gapsg = HiddenGroup(g1, 3, 2, NULL);
6036    bip->gapped = HiddenGroup(gapsg, 0, 2, NULL);
6037    RadioButton(bip->gapped, "gapped");
6038    RadioButton(bip->gapped, "ungapped");
6039    SetValue(bip->gapped, 1);
6040 
6041    g2 = NormalGroup(localg, 1,1, "",  systemFont,NULL);
6042    maskg=HiddenGroup(g2, 0, 2, NULL);
6043    bip->maskrep = CheckBox(maskg, "Mask Repeats", NULL);
6044    SetStatus(bip->maskrep, FALSE);
6045    bip->masksimple = CheckBox(maskg, "Mask Simple Sequence", NULL);
6046    SetStatus(bip->masksimple, TRUE);
6047    */
6048 
6049    bottomg=HiddenGroup(maingroup, 1, 2, NULL);
6050 
6051    localg = NormalGroup(bottomg, 1, 3, "Local Alignment Options", systemFont, NULL);
6052 
6053    g3 = NormalGroup(localg, 1,1, "",  systemFont,NULL);
6054    eANDwg = HiddenGroup(g3, 2, 2, NULL);
6055    StaticPrompt(eANDwg, "hitlist:  e-", 0, 0, systemFont, 'l');
6056    bip->eval = DialogText(eANDwg, "10", 5, NULL);
6057    StaticPrompt(eANDwg, "wordsize:", 0, 0, systemFont, 'l');
6058    bip->wordsize = DialogText(eANDwg, "11", 5, NULL);
6059 
6060 
6061    submitg=HiddenGroup(bottomg, 2, 0, NULL);
6062    b = PushButton(submitg, "BLAST", DOT_DoBlast);
6063    b1 = PushButton(submitg, "Cancel", DOT_CancelBlast);
6064    SetObjectExtra(b1, (Pointer)bip, StdCleanupExtraProc);
6065    SetObjectExtra(b, (Pointer)bip, StdCleanupExtraProc);
6066    Show(w);
6067 
6068    return;
6069 
6070 
6071 }
6072 
6073 
6074 static void DOT_Blast2SeqProc (IteM i)
6075 
6076 {
6077   DOTVibDataPtr          vdp;
6078   WindoW              w;
6079   
6080   w= (WindoW)ParentWindow(i);
6081   vdp=(DOTVibDataPtr)GetObjectExtra(w);
6082   if (vdp==NULL) return;
6083   Enable(vdp->displayOpts1);
6084   DOT_SetupBlastWindow(vdp); 
6085 }
6086 
6087 /*________________________________________(DOT_FreeAlnList)_____________
6088 
6089 
6090   Purpose : Free list of alignments in align list, then free ptr.
6091 
6092 ____________________________________________________________________*/
6093 static void  DOT_FreeAlnList(DOTAlignInfoPtr alp)
6094 {
6095   Int4 j, index;
6096   DOTAlnPtr PNTR alnL, aln;
6097 
6098   if (alp->Alnlist) 
6099     {
6100       alnL=alp->Alnlist;
6101       index=alp->index;
6102       
6103       for(j = 0; j < index; j++) 
6104         {
6105           aln=alnL[j];
6106           if (aln) MemFree(aln);
6107         }
6108       
6109       if (alnL) MemFree(alnL);
6110     }
6111 }
6112 /*____________________________________________(DOT_ExitAlign)___________
6113 
6114 
6115   Purpose : Clears alignment structure
6116 
6117 ____________________________________________________________________*/
6118 static void DOT_ExitAlign(DOTAlignInfoPtr alp){
6119 
6120 
6121   if (alp->Alnlist)
6122     DOT_FreeAlnList(alp);
6123   
6124   if (alp->pict)
6125     DeletePicture(alp->pict);
6126   if (alp->is_na && alp->matrix)
6127     Free(alp->matrix);
6128 
6129   if (alp) MemFree(alp);
6130 
6131 }
6132 /*_______________________________________________(DOT_QuitMainWindow)___
6133 
6134   Purpose : Quit Main window.
6135 
6136 ____________________________________________________________________*/
6137 
6138 static void DOT_CloseMainWindow (IteM i)
6139 
6140 {
6141   WindoW  w;
6142   DOTVibDataPtr vdp;
6143   DOTSelDataPtr  data;
6144 
6145   w=(WindoW)ParentWindow(i);
6146   vdp=(DOTVibDataPtr)GetObjectExtra(w);  
6147   data=(DOTSelDataPtr)vdp->data;
6148   if (data) MemFree(data);
6149 
6150   if (vdp->xname) MemFree(vdp->xname);
6151   if (vdp->yname) MemFree(vdp->yname);
6152   if (vdp->mip)
6153     DOT_FreeMainInfoPtrEx(vdp->mip);
6154 
6155   if (vdp->alp)
6156     {
6157       if (vdp->alp->Alnlist)
6158         DOT_FreeAlnList(vdp->alp);
6159       if (vdp->alp) MemFree(vdp->alp);
6160     }
6161   if (vdp) MemFree(vdp);
6162   
6163   Remove(w);
6164 }
6165 
6166 static void DOT_ExitProgram(IteM i)
6167 {
6168   DOT_CloseMainWindow(i);
6169   QuitProgram();
6170 }
6171 /*________________________________________(DOT_GridProc)_____________
6172 
6173   Purpose : Show or Hide the grid on Main window.
6174 
6175 ____________________________________________________________________*/
6176 
6177 static void DOT_GridProc (ChoicE i) 
6178 {
6179   WindoW      w;
6180   DOTVibDataPtr  vdp;
6181   Int4        value;
6182   
6183 
6184   w = (WindoW)ParentWindow(i);
6185   vdp = (DOTVibDataPtr)GetObjectExtra (w);
6186 
6187   value = GetValue(i);
6188   if (value==1)
6189     vdp->showGrid = TRUE;
6190   else
6191     vdp->showGrid = FALSE;
6192 
6193   DOT_UpdateMainPanel(vdp, TRUE);
6194   
6195 }
6196 
6197 /*________________________________________(DOT_CreateWindowDetails)____
6198 
6199   Purpose : Create buttons on the main window.
6200 
6201 */
6202 static void DOT_CreateWindowDetails (WindoW w, DOTVibDataPtr vdp)
6203 {
6204   GrouP          g, g1, g2;
6205   Char           PNTR qname, PNTR sname;
6206   Int4           q_start, q_stop, s_start, s_stop;
6207   RecT           rc;
6208   Int4           Xpixels, Ypixels, pixwidth;
6209   DOTMainDataPtr     mip=NULL;
6210   DOTAlignInfoPtr    alp=NULL;
6211   PrompT             pr1, pr2;
6212 
6213   
6214   if (vdp->mip)
6215     mip=vdp->mip;
6216   if (vdp->alp)
6217     alp=vdp->alp;
6218   ObjectRect(w, &rc);
6219   pixwidth=rc.right-rc.left-10;
6220   g=HiddenGroup(w, 0, 3, NULL); 
6221   SetGroupSpacing(g, 10, 20);
6222   g1=HiddenGroup(g, 7, 0, NULL);
6223   g2=HiddenGroup (g,4, 0, NULL);  
6224   SetGroupSpacing(g2, 3, 0);
6225   pr2=StaticPrompt (g2, "Threshold-Ramp:", 0, 3*vdp->Fh/2, vdp->Fnt, 'l');
6226   pr1=StaticPrompt (g2, "  20%", 0, 3*vdp->Fh/2, vdp->Fnt, 'l');
6227   vdp->sdp.ScrollBar = ScrollBar (g2, 15, 5, DOT_ChangeMainViewerCutoff);
6228   pr1=StaticPrompt (g2, "100%", 0, 3*vdp->Fh/2, vdp->Fnt, 'l');
6229   if(mip){
6230     qname=mip->qname;
6231     sname=mip->sname;
6232     q_start=mip->q_start;
6233     s_start=mip->s_start;
6234     q_stop=mip->q_stop;
6235     s_stop=mip->s_start;
6236   }
6237   else if (alp){
6238     qname=alp->name1;
6239     sname=alp->name2;
6240     q_start=1;
6241     s_start=1;
6242     q_stop=alp->xlen;
6243     s_stop=alp->ylen;
6244   }
6245   sprintf(vdp->iInfo, "%s (x-axis)[%d..%d]  vs.   %s (y-axis)[%d..%d]", qname, q_start, q_stop, sname, s_start, s_stop); 
6246   vdp->Infopanel= StaticPrompt (g, vdp->iInfo, pixwidth, popupMenuHeight, vdp->Fnt, 'l');  
6247   SetObjectExtra(vdp->sdp.ScrollBar, vdp, NULL);
6248   CorrectBarMax (vdp->sdp.ScrollBar, 80); /* 100% */
6249   CorrectBarValue (vdp->sdp.ScrollBar, 60);/* 100% */
6250   /* Main Panel*/
6251   Xpixels = 600;
6252   Ypixels = 600;
6253   vdp->panel = AutonomousPanel (w, Xpixels, Ypixels, DOT_DisplayHits,  DOT_VscrlProc, DOT_HscrlProc , 0, NULL, NULL);
6254   DOT_SetUpWin (w, vdp->panel, vdp);
6255   DOT_InitDataStruct(vdp);
6256   SetPanelClick (vdp->panel, DOT_ClickProc, DOT_DragProc, NULL, DOT_ReleaseProc);
6257 
6258 }
6259 
6260 /*________________________________________(DOT_ResizeMainWindow)_____________
6261 
6262   Purpose : Resize function for main window.
6263 
6264 ____________________________________________________________________*/
6265 static void DOT_ResizeMainWindow (WindoW w)
6266 {
6267   RecT        rcP, rcW, rcHsb, rcVsb;
6268   DOTVibDataPtr  vdp;
6269   WindoW      temport;
6270   Int2        height, width, in , gap;
6271   Int4        VCurPos, HCurPos, vsbWidth, hsbHeight;
6272   PaneL       p;
6273   BaR         vsb, hsb;
6274   DOTSelDataPtr   data;
6275 
6276 
6277   vdp = (DOTVibDataPtr) GetObjectExtra (w);
6278   if (vdp == NULL) return;
6279   p = vdp->panel;
6280   
6281   if (p == NULL) return; 
6282 
6283   ObjectRect (w, &rcW);
6284   width = rcW.right - rcW.left;
6285   height = rcW.bottom - rcW.top;
6286   vsb = GetSlateVScrollBar ((SlatE) p);
6287   hsb = GetSlateHScrollBar ((SlatE) p);
6288   
6289   SafeHide(vdp->Infopanel);
6290   SafeHide(p);
6291   Update();
6292 
6293   GetPosition(vsb,&rcVsb);
6294   GetPosition(hsb,&rcHsb);
6295   GetPosition (p, &rcP);
6296 
6297   in=2;
6298   gap=10;
6299   vsbWidth=rcVsb.right-rcVsb.left;
6300   hsbHeight=rcHsb.bottom-rcHsb.top;
6301 
6302   
6303   rcP.right = width - vsbWidth - in;
6304   rcP.bottom = height - hsbHeight -in;
6305 
6306   SetPosition (p, &rcP);
6307   AdjustPrnt (p, &rcP, FALSE);
6308 /*   Update(); */
6309 
6310   
6311   ObjectRect(p ,&rcP);
6312   temport=SavePort((WindoW)ParentWindow(p));
6313   Select(p);
6314 
6315   DOT_ComputePanelSize(rcP, vdp, &(vdp->sdp.PgWdth), &(vdp->sdp.PgLen));
6316   DOT_SetScrlVals (vdp);
6317   if (vdp->data)
6318     {
6319       data=(DOTSelDataPtr)vdp->data;
6320       DOT_UpdateDataRects(data, rcP, vdp, FALSE);
6321     }
6322 
6323   /*update scroll status*/
6324   VCurPos=GetBarValue(vsb);
6325   HCurPos=GetBarValue(hsb);
6326   DOT_VScrlUpdate(vdp, vsb, VCurPos);
6327   DOT_HScrlUpdate(vdp, hsb, HCurPos);
6328   
6329 /*   InvalRect(&rcP); */
6330   RestorePort(temport);
6331   SafeShow(vdp->Infopanel);
6332   SafeShow(vdp->panel);
6333   Update();
6334   
6335 }
6336 
6337 /*_______________________________________________(DOT_NewAnalysis)___
6338 
6339 
6340   Purpose : Close old windows, begin new analysis.
6341 
6342 ____________________________________________________________________*/
6343 static void DOT_NewAnalysis (ButtoN b)
6344 {
6345   WindoW     w;
6346   DOTVibDataPtr vdp;
6347   DOTSelDataPtr  data;
6348   
6349   w = (WindoW)ParentWindow (b);
6350   
6351   if (w!= NULL)
6352     {
6353       vdp = (DOTVibDataPtr)GetObjectExtra(w);
6354       data=(DOTSelDataPtr)vdp->data;
6355       if (data)
6356         MemFree(data);
6357       if (vdp)
6358         {
6359           if (vdp->mip)
6360             DOT_FreeMainInfoPtrEx(vdp->mip);
6361           MemFree(vdp);
6362         }
6363       Remove(w);
6364     }
6365 
6366   if (vdp->ChildWin!= NULL)
6367     {
6368       DOT_CloseSequenceWindow(b);
6369     }
6370 
6371 }
6372 
6373 
6374 /*____________________________________________(DOT_InitFont)_____________
6375 
6376 
6377   Purpose : Get font.
6378 
6379 ____________________________________________________________________*/
6380 
6381 static void DOT_InitFont (DOTVibDataPtr vdp)
6382 {
6383 #ifdef WIN_MAC
6384   vdp->Fnt = ParseFont ("Monaco, 9");
6385 #endif
6386 
6387 #ifdef WIN_MSWIN
6388   vdp->Fnt = ParseFont ("Courier, 7");
6389 #endif
6390 
6391 #ifdef WIN_MOTIF
6392   vdp->Fnt = ParseFont ("fixed, 12");
6393 #endif
6394 
6395         return;
6396 
6397 }
6398 
6399 /*____________________________________________(DOT_InitVibData)____________
6400 
6401 
6402   Purpose : Initialize DOTVibDataPtr for main window.
6403 
6404 ____________________________________________________________________*/
6405 
6406 static void DOT_InitVibData(DOTVibDataPtr vdp)
6407 {
6408 
6409 
6410   vdp->sdp.TrampPos=75;
6411   vdp->showGrid=TRUE;
6412   vdp->showDotPlot=TRUE;
6413 
6414   DOT_InitFont(vdp);
6415   SelectFont(vdp->Fnt);
6416 /*   vdp->charw=MaxCharWidth(); */
6417 /*   vdp->Fh=FontHeight(); */
6418   /* temporarily while being called from ingenue */
6419   vdp->charw = 15;
6420   vdp->Fh = 17;
6421   vdp->VERT_MARGIN = 50;
6422   vdp->HORZ_MARGIN = 80;
6423   vdp->selectMode = 1;
6424 
6425 }
6426 /*________________________________________(DOT_OpenSeqAnnotFile)_____________
6427 
6428 
6429   Purpose : Open a seqannot file with a seqalign and update the viewer.
6430 
6431 ____________________________________________________________________*/
6432 static void DOT_OpenSeqAnnotFile(IteM i)
6433 {
6434   DOTVibDataPtr vdp;
6435   FILE*         afile;
6436   Char      path [PATH_MAX];
6437   Pointer         dataptr=NULL;
6438   Uint2           datatype;
6439   SeqAnnotPtr     sanp=NULL;
6440   SeqAlignPtr     sap=NULL;
6441   DOTAlignInfoPtr alp;
6442 
6443 
6444   vdp=(DOTVibDataPtr)GetObjectExtra(ParentWindow(i));
6445   
6446   if (GetInputFileName(path, sizeof(path), "", "TEXT"))
6447     {
6448       if (path != NULL)
6449         {
6450           if (!(afile = FileOpen(path, "r"))){     
6451             ErrPostEx(SEV_FATAL, 0, 0, "file not found");
6452             return;
6453           } 
6454           dataptr = ReadAsnFastaOrFlatFile (afile, &datatype, NULL, FALSE, FALSE, TRUE, FALSE);
6455           if (!dataptr){     
6456             ErrPostEx(SEV_FATAL, 0, 0, "bad seqannot file");
6457               goto end;
6458           }
6459           sanp = (SeqAnnotPtr)(dataptr);
6460           sap = (SeqAlignPtr)(sanp->data);
6461           if (!sap){     
6462             ErrPostEx(SEV_FATAL, 0, 0, "bad seqannot file");
6463               goto end;
6464           } 
6465           if (sap->saip != NULL)
6466             AMAlignIndex2Free2(sap);
6467           sap->saip=NULL;
6468           AlnMgr2IndexLite(sap);
6469           AlnMgr2SortAlnSetByNthRowPos(sap, 1);
6470 
6471           Enable((Nlm_Handle)vdp->displayOpts1);
6472           if (vdp->alp){ /* discard previous alignment*/
6473             vdp->alp->pict=NULL;
6474             DOT_ExitAlign(vdp->alp);
6475           }
6476           alp=DOT_AlignInfoNew();
6477           alp->sap = sap;
6478           if (!DOT_FillAlignInfoPointer(alp)){
6479             vdp->showALIGN=FALSE;
6480             goto end;
6481           }
6482           vdp->alp=alp;
6483           vdp->showALIGN=TRUE;
6484           SetValue(vdp->displayOpts2, 2);
6485         }
6486 
6487     end:
6488       DOT_UpdateMainPanel(vdp, TRUE);
6489       fclose(afile);
6490     }
6491 
6492   return;
6493 }
6494 
6495 /*________________________________________(DOT_MakeMainViewer)_____________
6496 
6497 
6498   Purpose : Create main window.
6499 
6500 ____________________________________________________________________*/
6501 
6502 NLM_EXTERN Boolean DOT_MakeMainViewer (DOTMainDataPtr mip, DOTAlignInfoPtr alp)
6503 {
6504   WindoW         w;
6505   Int2           margins;
6506   MenU               m1, m2, m3, m4, s1, s2;
6507   IteM           i;
6508   ChoicE         ch;
6509   DOTVibDataPtr  vdp;
6510   SeqAlignPtr    sap=NULL;
6511   Char           title[60]={""};
6512 
6513   if (!mip && !alp) return FALSE;
6514   vdp=(DOTVibDataPtr)MemNew(sizeof(DOTVibData));
6515   if (!vdp) return FALSE;
6516   DOT_InitVibData(vdp);
6517   margins = 4*stdCharWidth;
6518   if (mip){
6519     vdp->mip=mip;
6520     vdp->xlen=mip->qlen;
6521     vdp->ylen=mip->slen;
6522     vdp->xstart=mip->q_start;
6523     vdp->ystart=mip->s_start;
6524     vdp->xstop=mip->q_stop;
6525     vdp->ystop=mip->s_stop;
6526     vdp->xname=mip->qname;
6527     vdp->yname=mip->sname;
6528     vdp->strand1=mip->qstrand;
6529     vdp->strand2=mip->sstrand;
6530     vdp->showDotPlot=TRUE;
6531   } else if (alp){
6532     sap=alp->sap;
6533     vdp->alp=alp;
6534     if(!mip){
6535       vdp->xlen=alp->xlen;
6536       vdp->ylen=alp->ylen;
6537       vdp->xstart=alp->xstart;
6538       vdp->ystart=alp->ystart;
6539       vdp->xstop=alp->xstart+alp->xlen-1;
6540       vdp->ystop=alp->ystart+alp->ylen-1;
6541       vdp->xname=alp->name1;
6542       vdp->yname=alp->name2;
6543       vdp->strand1=AlnMgr2GetNthStrand(alp->sap, 1);
6544       vdp->strand2=AlnMgr2GetNthStrand(alp->sap, 2);
6545     }
6546     vdp->showALIGN=TRUE;
6547   }
6548   sprintf(title, "%s", vdp->xname);
6549   StringCat(title, "  vs. ");
6550   StringCat(title, vdp->yname);
6551 #ifdef WIN_MAC
6552   DOT_SetupMenus ();
6553 #endif
6554   w = DocumentWindow (margins, margins, 800, 800, title, StdCloseWindowProc,   DOT_ResizeMainWindow);
6555 #ifndef WIN_MAC
6556   DOT_SetupMenus (); 
6557 #endif
6558   SetObjectExtra(w, (Pointer)vdp, NULL);
6559   m1 = PulldownMenu (w, "File"); 
6560 /*   CommandItem (m1, "New analysis", DOT_NewAnalysis);  */
6561   i=CommandItem(m1, "Alignment (SeqAnnot) File...", DOT_OpenSeqAnnotFile);
6562   Disable(i);
6563   CommandItem (m1, "Close",DOT_CloseMainWindow); 
6564   SeparatorItem(m1);
6565   i = CommandItem (m1, "Exit",DOT_ExitProgram); 
6566 #ifndef DOT_STANDALONE
6567   Disable(i);
6568 #endif
6569   m2 = PulldownMenu (w, "Options"); 
6570   vdp->displayOpts1=SubMenu(m2,"Display");
6571   if (!sap) Disable((Nlm_Handle)vdp->displayOpts1);
6572   vdp->displayOpts2=ChoiceGroup (vdp->displayOpts1, DOT_DisplayOptsProc);
6573   ChoiceItem (vdp->displayOpts2, "Dots ONLY");
6574   ChoiceItem (vdp->displayOpts2, "Dots & Aligns"); 
6575   ChoiceItem (vdp->displayOpts2, "Aligns ONLY"); 
6576   SetValue(vdp->displayOpts2,2); 
6577   SeparatorItem(m2);
6578   s1=SubMenu(m2,"Grid");
6579   ch=ChoiceGroup (s1, DOT_GridProc);
6580   ChoiceItem (ch, "show"); 
6581   ChoiceItem (ch, "hide");
6582   SeparatorItem(m2);
6583   s2=SubMenu(m2,"Select Mode");
6584   Disable(s2);
6585   ch=ChoiceGroup (s2, DOT_ModeProc);
6586   ChoiceItem (ch, "Sequence"); 
6587   ChoiceItem (ch, "Features");
6588   SetValue(ch, 1);
6589   SeparatorItem(m2);
6590   i = CommandItem (m2, "Parameters ..", DOT_ParametersProc); 
6591   SetObjectExtra(i, vdp, NULL);
6592   Disable(i);
6593   m3 = PulldownMenu(w, "Resize");
6594   i = CommandItem (m3, "Reduce", DOT_ReduceSizeProc); 
6595   i = CommandItem (m3, "Enlarge", DOT_EnlargeSizeProc); 
6596   i = CommandItem (m3, "Original", DOT_OriginalSizeProc);
6597   i = CommandItem (m3, "Zoom into region..", DOT_ZoomProc); 
6598   SetObjectExtra(i, vdp, NULL);
6599   m4 = PulldownMenu (w, "Analysis"); 
6600   i = CommandItem(m4, "Blast2Seq ..", DOT_Blast2SeqProc);
6601   if (!mip && alp)
6602     Disable(i);
6603   vdp->MainWin = w;
6604   DOT_CreateWindowDetails(w, vdp);
6605   RealizeWindow(w);
6606   Show (w);
6607   ProcessEvents();
6608   return TRUE;
6609 }
6610 
6611 
6612 static void DOT_SetColor(SegmenT  seg1, Int1 code, Boolean is_autopanel)
6613 {
6614 
6615   if (!is_autopanel){
6616   if (code==dotaln_BEST)
6617     AddAttribute(seg1, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
6618   if (code==dotaln_OUTLYING_LARGE)
6619     AddAttribute(seg1, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
6620   if (code==dotaln_OUTLYING_SMALL)
6621     AddAttribute(seg1, COLOR_ATT, GREEN_COLOR, 0, 0, 0, 0);
6622   if (code==dotaln_GENERAL)
6623     AddAttribute(seg1, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
6624   }
6625   else{
6626   if (code==dotaln_BEST)
6627     Red();
6628   if (code==dotaln_OUTLYING_LARGE)
6629     Blue();
6630   if (code==dotaln_OUTLYING_SMALL)
6631     Green();
6632   if (code==dotaln_GENERAL)
6633     Black();
6634   }
6635 
6636 }
6637 
6638 
6639 static Boolean DOT_DeselectPrim (SegmenT seg, PrimitivE prim, Uint2 segID,Uint2 primID, Uint2 primCt, VoidPtr userdata)
6640 
6641 {
6642 
6643   Int1  highlight;
6644   VieweR  v;
6645 
6646   v = (VieweR)userdata;
6647   GetPrimDrawAttribute (prim, NULL, NULL, NULL, NULL, NULL, &highlight);
6648   if (highlight != PLAIN_PRIMITIVE) 
6649     HighlightPrimitive (v, seg, prim, PLAIN_PRIMITIVE);
6650 
6651   return TRUE;
6652 }
6653 
6654 static DOTAlnPtr DOT_FindAlignment(DOTVibDataPtr vdp2, Uint2 primID)
6655 {
6656   DOTAlnPtr aln, salp;
6657   DOTAlnPtr PNTR alnL;
6658   DOTSelDataPtr data;
6659   Boolean   lt_fixed=FALSE, rb_fixed=FALSE;
6660 
6661 
6662   if (!vdp2->alp && !vdp2->alp->Alnlist) return NULL;
6663   salp=(DOTAlnPtr)MemNew(sizeof(DOTAln));
6664   salp->show=align_plot;
6665   data=vdp2->data;
6666   alnL=vdp2->alp->Alnlist;
6667   aln=alnL[primID-1];
6668   salp->sap=aln->sap;
6669   salp->q_start=aln->q_start;
6670   salp->q_stop=aln->q_stop;
6671   salp->s_start=aln->s_start;
6672   salp->s_stop=aln->s_stop;
6673   salp->primID=(Uint2)primID;
6674 
6675   return salp;
6676 }
6677 
6678 
6679 /*____________________________________________(DOT_AlignPlotGivenSeqAlign)_____________
6680 
6681 
6682   Purpose : Run alignment display given seqalignpointer
6683 
6684 ____________________________________________________________________*/
6685 NLM_EXTERN Boolean DOT_AlignPlotGivenSeqAlign(SeqAlignPtr sap)
6686 {
6687   DOTAlignInfoPtr alp;
6688 
6689   alp=DOT_AlignInfoNew();
6690   alp->sap = sap;
6691   alp->entityID = sap->idx.entityID;
6692   if (!DOT_FillAlignInfoPointer(alp)){
6693     MemFree(alp);
6694     return FALSE;
6695   }
6696 
6697   if (!DOT_MakeMainViewer(NULL, alp))
6698     return FALSE;
6699   return TRUE;
6700 }
6701 /*____________________________________________(DOT_AlignPlotGivenScp)_____________
6702 
6703 
6704   Purpose : Run alignment display given seqalignpointer
6705 
6706 ____________________________________________________________________*/
6707 NLM_EXTERN Boolean DOT_AlignPlotGivenScp(SCP_ResultPtr scp)
6708 {
6709   DOTAlignInfoPtr alp;
6710 
6711   alp=DOT_AlignInfoNew();
6712   alp->sap=NULL;
6713   alp->entityID=scp->saps[0]->idx.entityID;
6714   alp->itemID=1;
6715   if (!DOT_FillFromScp(alp, scp)){
6716     MemFree(alp);
6717     return FALSE;
6718 /*     QuitProgram(); */
6719   }
6720   if (!DOT_MakeMainViewer(NULL, alp))
6721     return FALSE;
6722   return TRUE;
6723 }
6724 
6725 /*_______________________________(DOT_RegDiagsDisplay)_____
6726 
6727 
6728   Purpose : Registered function for Dot Diag display.
6729 
6730 _________________________________________________________*/
6731 
6732 NLM_EXTERN Int2 LIBCALLBACK DOT_RegDiagsDisplay(Pointer data)
6733 {
6734   OMProcControlPtr    ompcp = NULL;
6735   SeqAlignPtr         sap = NULL;
6736   
6737   ompcp = (OMProcControlPtr) data;
6738   if (ompcp == NULL || ompcp->proc == NULL) {
6739     ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [1]");
6740     return OM_MSG_RET_ERROR;
6741   }
6742   
6743   switch (ompcp->input_itemtype) {
6744   case OBJ_SEQALIGN :
6745     sap = (SeqAlignPtr) ompcp->input_data;
6746     break;
6747   case 0 :
6748     return OM_MSG_RET_ERROR;
6749   default :
6750     return OM_MSG_RET_ERROR;
6751   }
6752   
6753   if (sap == NULL) {
6754     ErrPostEx (SEV_ERROR, 0, 0, "Input Data is NULL or is not a seqalign");
6755     return OM_MSG_RET_ERROR;
6756   }
6757 
6758   if (!DOT_AlignPlotGivenSeqAlign(sap))
6759     return OM_MSG_RET_ERROR;
6760   else 
6761     return OM_MSG_RET_DONE;
6762 
6763 }
6764 
6765 
6766 /*_______________________________(Scoop Functions)_____
6767 
6768 
6769   Purpose : Run Blast 2 Seqs and sort results into high scoring, large outlying and small outlying alignments.
6770 
6771 _________________________________________________________*/
6772 
6773 
6774 NLM_EXTERN SCP_ResultPtr SCP_CompareOrderOrganizeBioseqs(BioseqPtr bsp1, BioseqPtr bsp2, SeqLocPtr slp1, SeqLocPtr slp2, CharPtr progname, Int4 wordsize, Int4 hitlist_size)
6775 {
6776    Int4                 i;
6777    BLAST_OptionsBlkPtr  options;
6778    SeqAlignPtr          sap;
6779    SeqAlignPtr          sap_head;
6780    SeqAlignPtr          sap_prev;
6781    SCP_ResultPtr        scp;
6782    SCP_ResultPtr        scp_large;
6783    SCP_ResultPtr        scp_small;
6784    Int4                 start;
6785    Int4                 stop;
6786    SeqAnnotPtr          sanp;
6787    SeqEntryPtr          sep;
6788    Uint2                entityID=0;
6789    Uint4                itemID=0;
6790 
6791    if (bsp1 == NULL || bsp2 == NULL)
6792       return NULL;
6793    options = BLASTOptionNew(progname, FALSE);
6794    options->filter_string = StringSave("m L;R");
6795    options->expect_value = 10;
6796    /* Fasika's changes */
6797 
6798    options->hitlist_size = hitlist_size;
6799    options->wordsize = wordsize;
6800    if (slp1 !=NULL && slp2 !=NULL){
6801      sap = BlastTwoSequencesByLoc(slp1, slp2, progname, options);
6802    }
6803    else {
6804      sap = BlastTwoSequences(bsp1, bsp2, progname, options);
6805    }
6806 
6807    sep = SeqMgrGetSeqEntryForData (bsp1);
6808    entityID = ObjMgrGetEntityIDForChoice(sep);
6809    sanp = SeqAnnotForSeqAlign (sap);
6810    if (sanp == NULL) return NULL;
6811    entityID =DOT_AttachSeqAnnotToSeqEntry(entityID, sanp, bsp1);
6812    SeqMgrIndexFeatures (entityID, (Pointer)bsp1);
6813    itemID =GatherItemIDByData(entityID, OBJ_BIOSEQ, (Pointer)bsp1);
6814    /* end of Fasika's changes */
6815 
6816    AlnMgr2IndexLite(sap);
6817    scp = (SCP_ResultPtr)MemNew(sizeof(SCP_Result));
6818    scp->len1=bsp1->length;
6819    scp->len2=bsp2->length;
6820    SCP_OrganizeAlnsInSet(sap, SCP_FUZZ, scp, 1);
6821    BLASTOptionDelete(options);
6822    fprintf(stdout, "Sequence 1 length: %d\n", bsp1->length);
6823    fprintf(stdout, "Sequence 2 length: %d\n", bsp2->length);
6824    SCP_GetNthSeqRangeInSASet(scp->saps, scp->numsaps, 1, &start, &stop);
6825    fprintf(stdout, "The best alignments cover from %d to %d of sequence 1\n", start, stop);
6826    scp_large = scp_small = NULL;
6827    if (scp->numlarge_outliers > 0)
6828    {
6829       sap_head = sap_prev = scp->large_outliers[0];
6830       for (i=1; i<scp->numlarge_outliers; i++)
6831       {
6832          sap_prev->next = scp->large_outliers[i];
6833          sap_prev = sap_prev->next;
6834       }
6835       sap = SeqAlignNew();
6836       sap->segtype = SAS_DISC;
6837       sap->segs = (Pointer)(sap_head);
6838       AlnMgr2IndexLite(sap);
6839       scp_large = (SCP_ResultPtr)MemNew(sizeof(SCP_Result));
6840       SCP_OrganizeAlnsInSet(sap, SCP_FUZZ, scp_large, 1);
6841       SCP_GetNthSeqRangeInSASet(scp_large->saps, scp_large->numsaps, 1, &start, &stop);
6842       fprintf(stdout, "Large repeats cover from %d to %d of sequence 1\n", start, stop);
6843    }
6844    if (scp->numsmall_outliers > 0)
6845    {
6846       sap_head = sap_prev = scp->small_outliers[0];
6847       for (i=1; i<scp->numsmall_outliers; i++)
6848       {
6849          sap_prev->next = scp->small_outliers[i];
6850          sap_prev = sap_prev->next;
6851       }
6852       sap = SeqAlignNew();
6853       sap->segtype = SAS_DISC;
6854       sap->segs = (Pointer)(sap_head);
6855       AlnMgr2IndexLite(sap);
6856       scp_small = (SCP_ResultPtr)MemNew(sizeof(SCP_Result));
6857       SCP_OrganizeAlnsInSet(sap, SCP_FUZZ, scp_small, 1);
6858       SCP_GetNthSeqRangeInSASet(scp_small->saps, scp_small->numsaps, 1, &start, &stop);
6859       fprintf(stdout, "Small repeats cover from %d to %d of sequence 1\n", start, stop);
6860    }
6861    return scp;
6862 }
6863 
6864 extern void SCP_OrganizeAlnsInSet(SeqAlignPtr sap, Int4 fuzz, SCP_ResultPtr scp, Int4 n)
6865 {
6866    AMAlignIndex2Ptr  amaip;
6867    Boolean          conflict;
6868    Int4             curr;
6869    Int4             i;
6870    Int4             indextype;
6871    SeqAlignPtr      large=NULL;
6872    SeqAlignPtr      large_outliers=NULL;
6873    SeqAlignPtr      keep=NULL;
6874    SeqAlignPtr      keepers=NULL;
6875    SeqAlignPtr      salp=NULL;
6876    SeqAlignPtr      salp_head=NULL;
6877    SeqAlignPtr      salp_prev=NULL;
6878    SeqAlignPtr      small=NULL;
6879    SeqAlignPtr      small_outliers=NULL;
6880    SCP_nPtr         PNTR spin=NULL;
6881    Int4             start;
6882    Int4             stop;
6883    Int4             strand;
6884 
6885    if (sap == NULL || sap->saip == NULL || sap->saip->indextype != INDEX_PARENT)
6886       return;
6887    if (n > 2)
6888       return;
6889    amaip = (AMAlignIndex2Ptr)(sap->saip);
6890    indextype = amaip->alnstyle;
6891    /* make sure that everything is on the plus strand of the nth sequence */
6892    for (i=0; i<amaip->numsaps; i++)
6893    {
6894       salp = amaip->saps[i];
6895       AssignIDsInEntity(1, OBJ_SEQALIGN, (Pointer)salp);
6896       strand = AlnMgr2GetNthStrand(salp, n);
6897       if (strand == Seq_strand_minus)
6898       {
6899          SAIndex2Free2(salp->saip);
6900          salp->saip = NULL;
6901          salp->next = NULL;
6902          SeqAlignListReverseStrand(salp);
6903          AlnMgr2IndexSingleChildSeqAlign(salp);
6904       }
6905    }
6906    /* spin structure: n1 = which alignment, n2 = start on first row, n3 =
6907       alignment length on 1st row, n4 = start on 2nd row, n5 = 2nd strand */
6908    spin = (SCP_nPtr PNTR)MemNew((amaip->numsaps)*sizeof(SCP_nPtr));
6909    for (i=0; i<amaip->numsaps; i++)
6910    {
6911       spin[i] = (SCP_nPtr)MemNew(sizeof(SCP_n));
6912       salp = amaip->saps[i];
6913       spin[i]->n1 = i;
6914       AlnMgr2GetNthSeqRangeInSA(salp, n, &start, &stop);
6915       spin[i]->n3 = stop - start;
6916       spin[i]->n2 = start;
6917       AlnMgr2GetNthSeqRangeInSA(salp, 3-n, &start, &stop);
6918       spin[i]->n4 = start;
6919       strand = AlnMgr2GetNthStrand(salp, 3-n);
6920       if (strand == Seq_strand_minus)
6921          spin[i]->n5 = -1;
6922       else
6923          spin[i]->n5 = 1;
6924    }
6925    HeapSort((Pointer)spin, (size_t)(amaip->numsaps), sizeof(SCP_nPtr), SCP_CompareSpins);
6926    strand = spin[0]->n5;
6927    for (i=1; i<amaip->numsaps; i++)
6928    {
6929       if (spin[i]->n5 != strand)
6930       {
6931          salp = amaip->saps[spin[i]->n1];
6932          salp->next = NULL;
6933          SeqAlignFree(salp);
6934          amaip->saps[spin[i]->n1] = NULL;
6935          spin[i]->n1 = -1;
6936       }
6937    }
6938    large_outliers = small_outliers = keepers = NULL;
6939    scp->numsaps++;
6940    salp = amaip->saps[spin[0]->n1];
6941    salp->next = NULL;
6942    keepers = keep = salp;
6943    for (curr=0; curr<amaip->numsaps; curr++)
6944    {
6945       if (spin[curr]->n1 != -1)
6946       {
6947          for (i=curr+1; i<amaip->numsaps; i++)
6948          {
6949             if (spin[i]->n1 != -1)
6950             {
6951                conflict = FALSE;
6952             /* check first for conflict on first row */
6953                if (spin[i]->n2 + spin[i]->n3 - 1 > spin[curr]->n2 + fuzz)
6954                {
6955                   if (spin[i]->n2 < spin[curr]->n2)
6956                      conflict = TRUE;
6957                }
6958                if (spin[i]->n2 < spin[curr]->n2 + spin[curr]->n3 - 1 - fuzz)
6959                {
6960                   if (spin[i]->n2 + spin[i]->n3 - 1 > spin[curr]->n2 + spin[curr]->n3 - 1)
6961                      conflict = TRUE;
6962                }
6963                if (spin[i]->n2 >= spin[curr]->n2)
6964                {
6965                   if (spin[i]->n2 + spin[i]->n3 - 1 <= spin[curr]->n2 + spin[curr]->n3 - 1)
6966                      conflict = TRUE;
6967                }
6968             /* then check for conflict and consistency on second row */
6969                if (spin[i]->n2 + spin[i]->n3 - 1 < spin[curr]->n2 + fuzz)
6970                {
6971                   if (strand == 1)
6972                   {
6973                      if (spin[i]->n4 + spin[i]->n3 - 1 > spin[curr]->n4 + fuzz)
6974                         conflict = TRUE;
6975                   } else if (strand == -1)
6976                   {
6977                      if (spin[curr]->n4 + spin[curr]->n3 - 1 - fuzz > spin[i]->n4)
6978                         conflict = TRUE;
6979                   }
6980                } else
6981                {
6982                   if (strand == 1)
6983                   {
6984                      if (spin[i]->n4 < spin[curr]->n4 + spin[curr]->n3 - fuzz)
6985                         conflict = TRUE;
6986                   } else if (strand == -1)
6987                   {
6988                      if (spin[i]->n4 + spin[i]->n3 - 1 - fuzz > spin[curr]->n4)
6989                         conflict = TRUE;
6990                   }
6991                }
6992                if (conflict)
6993                {
6994                   salp = amaip->saps[spin[i]->n1];
6995                   salp->next = NULL;
6996                   if (spin[i]->n3 >= SCP_LARGE)
6997                   {
6998                      scp->numlarge_outliers++;
6999                      if (large_outliers != NULL)
7000                      {
7001                         large->next = salp;
7002                         large = salp;
7003                      } else
7004                         large_outliers = large = salp;
7005                   } else
7006                   {
7007                      scp->numsmall_outliers++;
7008                      if (small_outliers != NULL)
7009                      {
7010                         small->next = salp;
7011                         small = salp;
7012                      } else
7013                         small_outliers = small = salp;
7014                   }
7015                   amaip->saps[spin[i]->n1] = NULL;
7016                   spin[i]->n1 = -1;
7017                }
7018             }
7019          }
7020       }
7021    }
7022    for (i=1; i<amaip->numsaps; i++)
7023    {
7024       if (spin[i]->n1 != -1)
7025       {
7026          scp->numsaps++;
7027          salp = amaip->saps[spin[i]->n1];
7028          salp->next = NULL;
7029          if (keepers == NULL)
7030             keepers = keep = salp;
7031          else
7032          {
7033             keep->next = salp;
7034             keep = salp;
7035          }
7036       }
7037    }
7038    scp->small_outliers = (SeqAlignPtr PNTR)MemNew((scp->numsmall_outliers)*sizeof(SeqAlignPtr));
7039    small = small_outliers;
7040    i = 0;
7041    while (small != NULL)
7042    {
7043       scp->small_outliers[i] = small;
7044       i++;
7045       small = small->next;
7046    }
7047    scp->large_outliers = (SeqAlignPtr PNTR)MemNew((scp->numlarge_outliers)*sizeof(SeqAlignPtr));
7048    large = large_outliers;
7049    i = 0;
7050    while (large != NULL)
7051    {
7052       scp->large_outliers[i] = large;
7053       i++;
7054       large = large->next;
7055    }
7056    scp->saps = (SeqAlignPtr PNTR)MemNew((scp->numsaps)*sizeof(SeqAlignPtr));
7057    keep = keepers;
7058    i = 0;
7059    while (keep != NULL)
7060    {
7061       scp->saps[i] = keep;
7062       i++;
7063       keep = keep->next;
7064    }
7065 
7066    salp_head = salp_prev = NULL;
7067    for (i=0; i<amaip->numsaps; i++)
7068    {
7069       MemFree(spin[i]);
7070       if (amaip->saps[i] != NULL)
7071       {
7072          amaip->saps[i]->next = NULL;
7073          if (salp_prev != NULL)
7074          {
7075             salp_prev->next = amaip->saps[i];
7076             salp_prev = salp_prev->next;
7077          } else
7078             salp_head = salp_prev = amaip->saps[i];
7079       }
7080    }
7081    sap->segs = (Pointer)(salp_head);
7082    AMAlignIndexFree(sap->saip);
7083    sap->saip = NULL;
7084    AlnMgrIndexLite(sap);
7085    MemFree(spin);
7086 }
7087 
7088 static int LIBCALLBACK SCP_CompareSpins(VoidPtr ptr1, VoidPtr ptr2)
7089 {
7090    SCP_nPtr  spin1;
7091    SCP_nPtr  spin2;
7092 
7093    spin1 = *((SCP_nPtr PNTR) ptr1);
7094    spin2 = *((SCP_nPtr PNTR) ptr2);
7095    if (spin1 == NULL || spin2 == NULL)
7096       return 0;
7097    if (spin1->n3 > spin2->n3)
7098       return -1;
7099    if (spin1->n3 < spin2->n3)
7100       return 1;
7101    if (spin1->n2 < spin2->n2)
7102       return -1;
7103    if (spin1->n2 > spin2->n2)
7104       return 1;
7105    return 0;
7106 }
7107 
7108 static void SCP_GetNthSeqRangeInSASet(SeqAlignPtr PNTR saparray, Int4 numsaps, Int4 n, Int4Ptr start, Int4Ptr stop)
7109 {
7110    Int4         i;
7111    SeqAlignPtr  salp;
7112    Int4         start_tmp;
7113    Int4         stop_tmp;
7114    Int4         tmp1;
7115    Int4         tmp2;
7116   
7117    start_tmp = stop_tmp = -1;
7118    for (i=0; i<numsaps; i++)
7119    {
7120       salp = saparray[i];
7121       if (n > salp->dim)
7122       {
7123          if (start)
7124             *start = -1;
7125          if (stop)
7126             *stop = -1;
7127          return;
7128       }
7129       AlnMgrGetNthSeqRangeInSA(salp, n, &tmp1, &tmp2);
7130       if (tmp1 < start_tmp || start_tmp == -1)
7131          start_tmp = tmp1;
7132       if (tmp2 > stop_tmp)
7133          stop_tmp = tmp2;
7134    }
7135    if (start)
7136       *start = start_tmp;
7137    if (stop)
7138       *stop = stop_tmp;
7139 }
7140 

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.