~ubuntu-branches/ubuntu/breezy/ncbi-tools6/breezy

« back to all changes in this revision

Viewing changes to api/gather.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2002-04-04 22:13:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020404221309-vfze028rfnlrldct
Tags: upstream-6.1.20011220a
ImportĀ upstreamĀ versionĀ 6.1.20011220a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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:  gather.c
 
27
*
 
28
* Author:  Jim Ostell, Jinghui Zhang, Jonathan Kans
 
29
*
 
30
* Version Creation Date:   10/7/94
 
31
*
 
32
* $Revision: 6.36 $
 
33
*
 
34
* File Description: 
 
35
*
 
36
* Modifications:  
 
37
* --------------------------------------------------------------------------
 
38
* Date     Name        Description of modification
 
39
* -------  ----------  -----------------------------------------------------
 
40
*
 
41
* $Log: gather.c,v $
 
42
* Revision 6.36  2001/11/15 18:47:13  kans
 
43
* fix to unindexed get next descriptor
 
44
*
 
45
* Revision 6.35  2001/11/15 18:34:52  kans
 
46
* added GetNextDescriptorUnindexed, requires AssignIDsInEntity be called first
 
47
*
 
48
* Revision 6.34  2001/07/06 17:27:38  kans
 
49
* AssignIDs does not clear deleteme flag
 
50
*
 
51
* Revision 6.33  2000/12/18 14:48:07  tatiana
 
52
* turn off reordering
 
53
*
 
54
* Revision 6.32  2000/02/07 16:48:34  kans
 
55
* fixed setting of context->index in SeqMgrGetNextFeatureByID
 
56
*
 
57
* Revision 6.31  2000/02/01 22:25:44  kans
 
58
* indexed speedup now returns features in itemID order, not position order, to allow simple diff of e2index
 
59
*
 
60
* Revision 6.30  2000/01/07 03:01:42  kans
 
61
* indexed speedup only if raw bioseq not part of segmented bioseq
 
62
*
 
63
* Revision 6.29  2000/01/07 02:48:13  kans
 
64
* useSeqMgrIndexes now works with get_feats_location and get_feats_product, should be suitable for e2index speedup
 
65
*
 
66
* Revision 6.28  2000/01/07 00:56:02  kans
 
67
* targeted bioseq presents features right after bioseq is visited
 
68
*
 
69
* Revision 6.27  2000/01/07 00:18:25  kans
 
70
* targeted bioseq gather visits each seqannot, presents features in seqannot index
 
71
*
 
72
* Revision 6.26  2000/01/06 23:32:13  kans
 
73
* targeted bioseq gather visits each seqfeat, checks against feature/bioseq index
 
74
*
 
75
* Revision 6.25  1999/11/30 17:07:51  egorov
 
76
* Protect against dividing by zero.
 
77
*
 
78
* Revision 6.24  1999/10/29 18:06:26  kans
 
79
* added GetPointerForIDs (with SW)
 
80
*
 
81
* Revision 6.23  1999/09/30 18:33:09  kans
 
82
* delete marked objects corrects gatherindex.prevlink on remaining objects
 
83
*
 
84
* Revision 6.22  1999/09/29 21:10:53  kans
 
85
* delete marked seqannot also frees seqannot if it has no remaining sap->data components
 
86
*
 
87
* Revision 6.21  1999/09/29 18:24:53  kans
 
88
* added DeleteMarkedObjects
 
89
*
 
90
* Revision 6.20  1999/09/28 18:10:15  kans
 
91
* added DeleteMarkedObjectsProc callback - not yet tested
 
92
*
 
93
* Revision 6.19  1999/09/28 12:10:24  kans
 
94
* finished implementing lightweight GatherObjectsInEntity
 
95
*
 
96
* Revision 6.18  1999/09/27 22:02:45  kans
 
97
* further implementation of lightweight gather replacement
 
98
*
 
99
* Revision 6.17  1999/09/27 17:46:59  kans
 
100
* uses GatherIndex structure
 
101
*
 
102
* Revision 6.16  1999/09/26 20:44:25  kans
 
103
* implemented most of VisitProc callbacks
 
104
*
 
105
* Revision 6.15  1999/09/26 00:17:14  kans
 
106
* VisitObjectsInEntity prototype added
 
107
*
 
108
* Revision 6.14  1999/09/25 01:46:08  kans
 
109
* AssignIDsInEntity split into internal function that can also call callback, EXTRA_OBJMGR_FIELDS values assigned to some objects
 
110
*
 
111
* Revision 6.13  1999/09/07 17:59:52  kans
 
112
* AssignIDsInEntity takes datatype and dataptr for when entityID is 0, allowing unlinked components to be updated
 
113
*
 
114
* Revision 6.12  1999/09/07 17:13:09  kans
 
115
* added AssignIDsInEntity
 
116
*
 
117
* Revision 6.11  1999/09/01 14:41:26  shavirin
 
118
* Adjusted functions gather_align_data() and get_align_ends() to accept
 
119
* discontinuous alignment type.
 
120
*
 
121
* Revision 6.10  1999/07/26 20:55:52  ostell
 
122
* added recursive support for SAS_DISC SeqAlign
 
123
*
 
124
* Revision 6.9  1999/03/16 13:17:28  ostell
 
125
* changes in SeqLocOffset() to deal with multi-interval seqloc which is
 
126
* a subset of a feature.
 
127
*
 
128
* Revision 6.8  1999/01/13 23:34:19  kans
 
129
* added GatherSpecificProcLaunch
 
130
*
 
131
* Revision 6.7  1998/08/24 18:27:07  kans
 
132
* removed solaris -v -fd warnings
 
133
*
 
134
* Revision 6.6  1998/06/23 16:53:37  zjing
 
135
* modify function check_reverse_strand
 
136
*
 
137
* Revision 6.5  1998/03/10 20:43:28  kans
 
138
* IGCCBuild now handles delta seqs
 
139
*
 
140
* Revision 6.4  1998/03/02 22:15:35  zjing
 
141
* fix gap collection in the minus strand in function gather_align_data
 
142
*
 
143
* Revision 6.3  1997/11/19 22:14:48  ostell
 
144
* added support for multithreaded programs
 
145
*
 
146
* Revision 6.2  1997/10/10 17:01:37  kans
 
147
* support for individual elements of OBJ_BIOSEQ_DELTA
 
148
*
 
149
* Revision 6.1  1997/09/30 19:59:35  zjing
 
150
* bug fixes in gather_align_data
 
151
*
 
152
* Revision 6.0  1997/08/25 18:05:46  madden
 
153
* Revision changed to 6.0
 
154
*
 
155
* Revision 5.15  1997/08/13 18:43:46  zjing
 
156
* correct errors in gather_align_data for tblastn and tblastx
 
157
*
 
158
* Revision 5.14  1997/07/01 15:16:33  zjing
 
159
* fix the strand in gathering continous std-seg
 
160
*
 
161
* Revision 5.13  1997/06/19 18:37:47  vakatov
 
162
* [WIN32,MSVC++]  Adopted for the "NCBIOBJ.LIB" DLL'ization
 
163
*
 
164
* Revision 5.12  1997/04/23 12:44:49  zjing
 
165
* correct a bug for tblastn display
 
166
*
 
167
 * Revision 5.10  1997/03/17  21:22:00  kans
 
168
 * detach bioseq/bioseq set didn't unlink gcp->sep->next
 
169
 *
 
170
 * Revision 5.9  1997/01/15  17:25:45  zjing
 
171
 * a kludge fix for ck_extreme to display the features across zero properly
 
172
 *
 
173
 * Revision 5.8  1996/12/16  19:43:37  ostell
 
174
 * added an attachment/replacement of a Seq-loc to a feature in AttachDataProc
 
175
 *
 
176
 * Revision 5.7  1996/11/05  18:00:03  zjing
 
177
 * fix the problem of integer overflow for gather_align_data and speed up the process
 
178
 *
 
179
 * Revision 5.6  1996/08/29  01:18:34  ostell
 
180
 * added GatherAddExtraLoc for codebreak and trna.atncodon mapping
 
181
 *
 
182
 * Revision 5.5  1996/08/09  20:28:55  epstein
 
183
 * eliminate update_seq_loc()
 
184
 *
 
185
 * Revision 5.4  1996/08/06  19:56:03  kans
 
186
 * for SEQLOC_WHOLE, must call SeqIdFindBest on bsp->id
 
187
 *
 
188
 * Revision 5.3  1996/06/17  21:49:42  zjing
 
189
 * fix in gather_align_data for multiple alignments
 
190
 *
 
191
 * Revision 5.2  1996/06/10  18:35:36  zjing
 
192
 * fix in get_end_diag_val
 
193
 *
 
194
 * Revision 5.1  1996/06/10  15:08:53  epstein
 
195
 * replace make_seq_loc() with SeqLocIntNew() and make_pnt_loc with SeqLocPntNew()
 
196
 *
 
197
 * Revision 5.0  1996/05/28  13:23:23  ostell
 
198
 * Set to revision 5.0
 
199
 *
 
200
 * Revision 4.30  1996/05/22  20:35:25  ostell
 
201
 * changed GatherProcLaunch to cycle through proceedures in priority
 
202
 * order looking for OM_MSG_RET_DONE return, instead of just launching
 
203
 * the first one found.
 
204
 *
 
205
 * Revision 4.29  1996/05/06  14:49:12  zjing
 
206
 * fix a strand in load_align_data
 
207
 *
 
208
 * Revision 4.28  1996/04/24  20:12:13  ostell
 
209
 * removed an uncessary variable
 
210
 *
 
211
 * Revision 4.27  1996/04/08  15:44:02  kans
 
212
 * IGCC build scopes on omdp->choice or scope->scope
 
213
 *
 
214
 * Revision 4.26  1996/03/08  18:12:38  zjing
 
215
 * fix in check_reverse_strand for gather_align_data
 
216
 *
 
217
 * Revision 4.25  1996/02/28  04:53:06  ostell
 
218
 * added ObjMgrHold suport
 
219
 *
 
220
 * Revision 4.23  1996/01/22  13:28:11  kans
 
221
 * cast first parameter of MemSet to (Pointer) for SunOS compiler
 
222
 *
 
223
 * Revision 4.22  1996/01/03  23:01:04  ostell
 
224
 * added GatherOverWrite() to support find/replace external to Gather
 
225
 *
 
226
 * Revision 4.21  1995/12/22  20:12:01  ostell
 
227
 * added protection for NULL pointer on scope in IGCCBuild
 
228
 *
 
229
 * Revision 4.20  1995/12/22  14:42:30  ostell
 
230
 * added do_not_reload_from_cache to GatherScope
 
231
 * modified calls to support it
 
232
 * changed default behavior of gather to load and reclock entities
 
233
 *
 
234
 * Revision 4.19  1995/12/20  22:55:36  kans
 
235
 * bsp added to FocusSeqEntry, and MemSet (OBJ_MAX+1) bug fixed (JZ)
 
236
 *
 
237
 * Revision 4.18  1995/12/20  19:19:39  ostell
 
238
 * added GatherContext.igccp field
 
239
 * added FocusSeqEntry() function
 
240
 *
 
241
 * Revision 4.17  1995/12/20  15:05:15  zjing
 
242
 * Fix gather_align_data to get the end gaps in master sequence
 
243
 *
 
244
 * Revision 4.16  1995/12/15  15:17:07  kans
 
245
 * bsp is now initialized in IGCCBuild
 
246
 *
 
247
 * Revision 4.15  1995/12/15  02:47:01  ostell
 
248
 * fix to scoping for multiple records with same SeqId
 
249
 *
 
250
 * Revision 4.14  1995/12/14  21:43:04  ostell
 
251
 * added scope protection to IGCCBuild to protect against mulitple copies
 
252
 *
 
253
 * Revision 4.13  1995/12/13  19:28:13  ostell
 
254
 * more support for OBJ_SEQHIST_ALIGN
 
255
 *
 
256
 * Revision 4.12  1995/12/13  18:50:42  ostell
 
257
 * added support for OBJ_SEQHIST_ALIGN
 
258
 *
 
259
 * Revision 4.11  1995/11/21  23:08:38  ostell
 
260
 * added support in GatherContext for gatherstack
 
261
 *
 
262
 * Revision 4.10  1995/11/06  21:29:03  ostell
 
263
 * added newid and convert_loc to GatherScope, and new_loc to GatherContext
 
264
 * added functions ReMapIntFuzz and SeqLocReMap to support them
 
265
 * This allows SeqLocs on features to be copied into a remapped form by gather
 
266
 *
 
267
 * Revision 4.9  1995/10/06  19:25:24  ostell
 
268
 * added fields "ignore_top" and "stop_on_annot" to GatherScope
 
269
 * if "ignore_top" is TRUE, features on seglevel 0 are ignored
 
270
 * if "stop_on_annot" is TRUE, segments are traversed to a maximum depth
 
271
 * of gsp->seglevel, but traversing is stopped as soon as an annotation is
 
272
 * found.
 
273
 *
 
274
 * Revision 4.8  1995/10/01  20:51:28  kans
 
275
 * made GatherItemByDataProc static
 
276
 *
 
277
 * Revision 4.7  1995/09/30  03:38:31  ostell
 
278
 * Changed ObjMgrMessage functions to pass a structure
 
279
 * Added support for selecting regions
 
280
 * Added ability to remove entity when no more views on it
 
281
 *
 
282
 * Revision 4.6  1995/09/27  19:50:09  zjing
 
283
 * .
 
284
 *
 
285
 * Revision 4.1  1995/08/16  17:48:34  kans
 
286
 * add a chain parameter for gather Seq-align (jz)
 
287
 *
 
288
 * Revision 4.0  1995/07/26  13:49:01  ostell
 
289
 * force revision to 4.0
 
290
 *
 
291
 * Revision 1.38  1995/07/10  15:51:59  kans
 
292
 * changes in gather_align_data (zjing)
 
293
 *
 
294
 * Revision 1.37  1995/07/08  15:22:09  ostell
 
295
 * Set ObjMgrDirtyFlag on Attach..,Detach..,ReplaceDataForProc
 
296
 *
 
297
 * Revision 1.36  1995/06/02  17:53:17  kans
 
298
 * add gather range to gather bioseq
 
299
 *
 
300
 * Revision 1.35  1995/06/01  21:53:55  kans
 
301
 * support for Seq-align (zjing)
 
302
 *
 
303
 * Revision 1.34  1995/05/19  15:49:37  kans
 
304
 * fixed bug in mapping minus strand intervals
 
305
 *
 
306
 * Revision 1.33  1995/05/15  21:46:05  ostell
 
307
 * added Log line
 
308
 *
 
309
*
 
310
*
 
311
*
 
312
* ==========================================================================
 
313
*/
 
314
 
 
315
#include <gather.h>
 
316
#include <edutil.h>
 
317
#include <subutil.h>
 
318
#include <objfdef.h>
 
319
#include <explore.h>
 
320
 
 
321
static Boolean NEAR GatherSeqEntryFunc PROTO((SeqEntryPtr sep, InternalGCCPtr igccp, Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope, Pointer PNTR prevlink));
 
322
static Boolean NEAR GatherItemFunc PROTO((Uint2 entityID, Uint2 itemID, Uint2 itemtype,
 
323
                                   Pointer userdata, GatherItemProc userfunc, Pointer dataptr,
 
324
                                                                   Boolean do_not_reload_from_cache));
 
325
static Boolean NEAR GatherAddToStack PROTO((GatherContextPtr gcp));
 
326
static void NEAR GatherAddExtraLoc PROTO((GatherContextPtr gcp, SeqLocPtr slp));
 
327
 
 
328
static void NEAR GatherAddExtraLoc (GatherContextPtr gcp, SeqLocPtr slp)
 
329
{
 
330
        SeqLocPtr PNTR tmp;
 
331
 
 
332
        gcp->extra_loc_cnt++;
 
333
        if (gcp->extra_loc_cnt > gcp->extra_loc_total)
 
334
        {
 
335
                tmp = gcp->extra_loc;
 
336
                gcp->extra_loc = MemNew((size_t)(sizeof(SeqLocPtr) *(gcp->extra_loc_total + 5)));
 
337
                MemMove (gcp->extra_loc, tmp,(size_t)(sizeof(SeqLocPtr) *
 
338
                        (gcp->extra_loc_total)));
 
339
                MemFree(tmp);
 
340
                gcp->extra_loc_total += 5;
 
341
        }
 
342
        gcp->extra_loc[gcp->extra_loc_cnt - 1] = slp;
 
343
        return;
 
344
}
 
345
 
 
346
static Boolean NEAR GatherAddToStack (GatherContextPtr gcp)
 
347
{
 
348
        GatherElementPtr tmp;
 
349
        Int2 oldsize;
 
350
                
 
351
        if (gcp == NULL)
 
352
                return FALSE;
 
353
 
 
354
        if (gcp->numstack <= gcp->indent)  /* expand stack */
 
355
        {
 
356
                oldsize = gcp->numstack;
 
357
                tmp = gcp->gatherstack;
 
358
                gcp->numstack = oldsize + 20;
 
359
                gcp->gatherstack = MemNew((size_t)(sizeof(GatherElement) * (gcp->numstack)));
 
360
                if (oldsize)
 
361
                {
 
362
                        MemCopy(gcp->gatherstack, tmp,  (size_t)(sizeof(GatherElement) * (oldsize)));
 
363
                        MemFree(tmp);
 
364
                }
 
365
        }
 
366
 
 
367
        tmp = gcp->gatherstack + gcp->indent;
 
368
        tmp->itemID = gcp->itemID;
 
369
        tmp->itemtype = gcp->thistype;
 
370
        tmp->tempload = gcp->tempload;
 
371
        tmp->thisitem = gcp->thisitem;
 
372
 
 
373
        return TRUE;
 
374
}
 
375
 
 
376
static Boolean ck_extreme(SeqLocPtr slp, BoolPtr across_zero)
 
377
{
 
378
        SeqLocPtr one_loc;
 
379
        SeqIdPtr sip;
 
380
        Boolean has_prev;
 
381
 
 
382
        *across_zero = FALSE;
 
383
        switch(slp->choice)
 
384
        {
 
385
                case SEQLOC_MIX:
 
386
                case SEQLOC_PACKED_PNT:
 
387
                case SEQLOC_PACKED_INT:
 
388
                   sip = SeqLocId(slp);
 
389
                   if(sip == NULL)
 
390
                        return FALSE;
 
391
                   one_loc = NULL;
 
392
                   has_prev = FALSE;
 
393
                   while((one_loc = SeqLocFindNext(slp, one_loc))!=NULL)
 
394
                   {
 
395
                        if(SeqLocStart(one_loc) == 0)
 
396
                        {
 
397
                                if(has_prev && SeqLocStrand(one_loc) != Seq_strand_minus)
 
398
                                        *across_zero = TRUE;
 
399
                                else if(!has_prev && SeqLocStrand(one_loc) == Seq_strand_minus)
 
400
                                        *across_zero = TRUE;
 
401
                        }
 
402
                        if(one_loc->choice == SEQLOC_NULL)
 
403
                                return FALSE;
 
404
                        has_prev = TRUE;
 
405
                   }
 
406
                   return TRUE;
 
407
 
 
408
                default:
 
409
                        return FALSE;
 
410
        }
 
411
}
 
412
 
 
413
static Boolean ck_parts_overlap(SeqLocPtr slp, SeqLocPtr seq_loc)
 
414
{
 
415
        SeqLocPtr one_loc;
 
416
 
 
417
        one_loc = NULL;
 
418
        while((one_loc = SeqLocFindNext(slp, one_loc))!=NULL)
 
419
        {
 
420
                if(one_loc->choice != SEQLOC_NULL)
 
421
                {
 
422
                        if(SeqLocCompare(one_loc, seq_loc) != SLC_NO_MATCH)
 
423
                                return TRUE;
 
424
                }
 
425
        }
 
426
 
 
427
        return FALSE;
 
428
}
 
429
        
 
430
 
 
431
/*****************************************************************************
 
432
*
 
433
*   SeqLocOffset(seq_loc, sfp_loc, range, offset)
 
434
*       returns FALSE if seq_loc does not overlap sfp_loc
 
435
*       else fills in range structure mapping sfp_loc to seq_loc
 
436
*       adds offset to final values
 
437
*       if (ends) will assure that left is always <= right
 
438
*
 
439
*****************************************************************************/
 
440
NLM_EXTERN Boolean SeqLocOffset (SeqLocPtr seq_loc, SeqLocPtr sfp_loc, GatherRangePtr range, Int4 offset)
 
441
{
 
442
  Uint1    strand_loc, strand_sfp;
 
443
  Int4 temp;
 
444
  SeqLoc sl;
 
445
  SeqInt si;
 
446
  Boolean across_zero;
 
447
  Int4 toffset, l, r, t;
 
448
  Boolean ltrunc, rtrunc;
 
449
  SeqLocPtr tslp;
 
450
 
 
451
  if (seq_loc == NULL || sfp_loc == NULL || range == NULL) {
 
452
    return FALSE;
 
453
  }
 
454
 
 
455
 
 
456
  if(ck_extreme(sfp_loc, &across_zero))
 
457
  {
 
458
        if(!across_zero)
 
459
        {
 
460
                si.from = SeqLocStart(sfp_loc);
 
461
                si.to = SeqLocStop(sfp_loc);
 
462
                si.strand = SeqLocStrand(sfp_loc);
 
463
                si.id = SeqLocId(sfp_loc);
 
464
                sl.choice = SEQLOC_INT;
 
465
                sl.data.ptrvalue = &si;
 
466
                sfp_loc = &sl;
 
467
        }
 
468
        else if(!ck_parts_overlap(sfp_loc, seq_loc))
 
469
                return FALSE;
 
470
                
 
471
  }
 
472
 
 
473
  strand_sfp = SeqLocStrand(sfp_loc);
 
474
 
 
475
  toffset = 0;
 
476
  l = INT4_MAX;
 
477
  r = -1;
 
478
  tslp = NULL;
 
479
 
 
480
  while ((tslp = SeqLocFindNext(seq_loc, tslp)) != NULL)
 
481
  {
 
482
        if (SeqLocCompare(tslp, sfp_loc)) {
 
483
 
 
484
                strand_loc = SeqLocStrand(tslp);
 
485
 
 
486
                t = GetOffsetInLoc(sfp_loc, tslp, SEQLOC_LEFT_END);
 
487
                if (t == -1) { /* truncated */
 
488
                        if (strand_loc == Seq_strand_minus)
 
489
                                t = toffset + SeqLocLen(tslp) - 1;
 
490
                        else
 
491
                                t = toffset;
 
492
                        
 
493
                        if (t < l)
 
494
                        {
 
495
                                l = t;
 
496
                                ltrunc = TRUE;
 
497
                        }
 
498
                }
 
499
                else if ((t + toffset) < l)
 
500
                {
 
501
                        l = t + toffset;
 
502
                        ltrunc = FALSE;
 
503
                }
 
504
 
 
505
                t = GetOffsetInLoc(sfp_loc, tslp, SEQLOC_RIGHT_END);
 
506
                if (t == -1)
 
507
                {
 
508
                        if (strand_loc == Seq_strand_minus)
 
509
                                t = toffset;
 
510
                        else
 
511
                                t = toffset + SeqLocLen (tslp) - 1;
 
512
                        if (t > r) {
 
513
                                r = t;
 
514
                                rtrunc = TRUE;
 
515
                        }
 
516
 
 
517
                }
 
518
                else if ((t + toffset) > r)
 
519
                {
 
520
                        rtrunc = FALSE;
 
521
                        r = t + toffset;
 
522
                }
 
523
 
 
524
        }
 
525
        toffset += SeqLocLen(tslp);
 
526
  }
 
527
 
 
528
  if (r == -1) /* didn't find it */
 
529
        return FALSE;
 
530
 
 
531
  range->l_trunc = ltrunc;
 
532
  range->r_trunc = rtrunc;
 
533
  range->left = l + offset;
 
534
  range->right = r + offset;
 
535
 
 
536
  strand_loc = SeqLocStrand(seq_loc);
 
537
 
 
538
  if (strand_loc == Seq_strand_minus)
 
539
        range->strand = StrandCmp(strand_sfp);
 
540
  else
 
541
  {
 
542
        if(strand_sfp == Seq_strand_unknown)
 
543
                strand_sfp = Seq_strand_plus;
 
544
        range->strand = strand_sfp;
 
545
  }
 
546
 
 
547
  if(range->left > range->right)
 
548
  {
 
549
        temp = range->left;
 
550
        range->left = range->right;
 
551
        range->right = temp;
 
552
  }
 
553
 
 
554
  return TRUE;
 
555
}
 
556
 
 
557
 
 
558
/*****************************************************************************
 
559
*
 
560
*   ReMapIntFuzz()
 
561
*
 
562
*****************************************************************************/
 
563
NLM_EXTERN IntFuzzPtr ReMapIntFuzz(IntFuzzPtr ifp, Boolean rev, SeqLocPtr seq_loc, SeqLocPtr sfp_loc, Int4 offset)
 
564
{
 
565
        IntFuzzPtr newfuzz=NULL;
 
566
        SeqInt si;
 
567
        SeqPnt sp;
 
568
        ValNode vn;
 
569
        GatherRange range;
 
570
        Int4 i;
 
571
 
 
572
        if (ifp == NULL) return newfuzz;
 
573
 
 
574
        newfuzz = MemNew(sizeof(IntFuzz));
 
575
        MemCopy(newfuzz, ifp, sizeof(IntFuzz));
 
576
 
 
577
        switch (ifp->choice)
 
578
        {
 
579
                case 1:      /* plus/minus - no changes */
 
580
                case 3:      /* percent - no changes */
 
581
                        break;
 
582
                case 2:      /* range */
 
583
                        vn.choice = SEQLOC_INT;
 
584
                        vn.next = NULL;
 
585
                        vn.data.ptrvalue = &si;
 
586
                        MemSet((Pointer)(&si), 0, sizeof(SeqInt));
 
587
                        si.id = SeqLocId(sfp_loc);
 
588
                        if (si.id == NULL)
 
589
                        {
 
590
                                newfuzz = MemFree(newfuzz);
 
591
                                break;
 
592
                        }
 
593
                        si.strand = SeqLocStrand(sfp_loc);
 
594
                        if (! SeqLocOffset(seq_loc, &vn, &range, offset))
 
595
                        {
 
596
                                newfuzz = MemFree(newfuzz);
 
597
                                break;
 
598
                        }
 
599
 
 
600
                        newfuzz->a = range.right;  /* max */
 
601
                        newfuzz->b = range.left;        /* min */
 
602
                        break;
 
603
                case 4:     /* lim */
 
604
                        if (rev)  /* reverse/complement */
 
605
                        {
 
606
                                switch (newfuzz->a)
 
607
                                {
 
608
                                        case 1:    /* greater than */
 
609
                                                newfuzz->a = 2;
 
610
                                                break;
 
611
                                        case 2:    /* less than */
 
612
                                                newfuzz->a = 1;
 
613
                                                break;
 
614
                                        case 3:    /* to right of residue */
 
615
                                                newfuzz->a = 4;
 
616
                                                break;
 
617
                                        case 4:    /* to left of residue */
 
618
                                                newfuzz->a = 3;
 
619
                                                break;
 
620
                                        default:
 
621
                                                break;
 
622
                                }
 
623
                        }
 
624
                        break;
 
625
                case 5:      /* alternate positions */
 
626
                        vn.choice = SEQLOC_PNT;
 
627
                        vn.next = NULL;
 
628
                        vn.data.ptrvalue = &sp;
 
629
                        MemSet((Pointer)(&si), 0, sizeof(SeqPnt));
 
630
                        sp.id = SeqLocId(sfp_loc);
 
631
                        if (sp.id == NULL)
 
632
                        {
 
633
                                newfuzz = MemFree(newfuzz);
 
634
                                break;
 
635
                        }
 
636
                        sp.strand = SeqLocStrand(sfp_loc);
 
637
 
 
638
                        newfuzz->alt = MemNew((size_t)(sizeof(Int4) * ifp->b));
 
639
                        newfuzz->a = 0;
 
640
 
 
641
                        for (i = 0; i < ifp->a; i++)
 
642
                        {
 
643
                                sp.point = ifp->alt[i];
 
644
 
 
645
                                if (SeqLocOffset(seq_loc, &vn, &range, offset))
 
646
                                {
 
647
                                        newfuzz->alt[newfuzz->a] = range.left;
 
648
                                        newfuzz->a++;
 
649
                                }
 
650
                        }
 
651
 
 
652
                        if (newfuzz->a == 0)
 
653
                                newfuzz = IntFuzzFree(newfuzz);
 
654
 
 
655
                        break;
 
656
                default:
 
657
                        newfuzz = MemFree(newfuzz);
 
658
                        break;
 
659
 
 
660
        }
 
661
        return newfuzz;
 
662
}
 
663
 
 
664
 
 
665
NLM_EXTERN SeqLocPtr SeqLocReMap (SeqIdPtr newid, SeqLocPtr seq_loc, SeqLocPtr head, Int4 offset, Boolean rev)
 
666
{
 
667
        GatherRange range;
 
668
        Uint1 the_strand;
 
669
 
 
670
        SeqLocPtr newhead = NULL, last=NULL, tmp, slp, prev, next, thead;
 
671
        SeqIntPtr sip, sip2;
 
672
        SeqPntPtr spp, spp2;
 
673
        PackSeqPntPtr pspp, pspp2;
 
674
        SeqBondPtr sbp, sbp2;
 
675
        Int4 numpnt, i, tpos, intcnt, othercnt;
 
676
        Pointer ptr = NULL;
 
677
        Boolean dropped_first, dropped_last, was_equiv = FALSE;
 
678
        IntFuzzPtr ifp, ifp1, ifp2;
 
679
        ValNode vn;
 
680
        SeqPnt sp;
 
681
        
 
682
        if ((head == NULL) || (seq_loc == NULL) || (newid == NULL)) return NULL;
 
683
 
 
684
        if (! SeqLocOffset(seq_loc, head, &range, offset))
 
685
                return NULL;
 
686
 
 
687
        switch (head->choice)
 
688
        {
 
689
                case SEQLOC_PACKED_PNT:
 
690
                        pspp = (PackSeqPntPtr)(head->data.ptrvalue);
 
691
                        numpnt = PackSeqPntNum(pspp);
 
692
 
 
693
                        sp.id = pspp->id;
 
694
                        sp.strand = pspp->strand;
 
695
                        sp.fuzz = NULL;
 
696
                        vn.next = NULL;
 
697
                        vn.choice = SEQLOC_PNT;
 
698
                        vn.data.ptrvalue = &sp;
 
699
 
 
700
                        pspp2 = PackSeqPntNew();
 
701
                        the_strand = range.strand;
 
702
                        intcnt = 0;          /* use for included points */
 
703
                        othercnt = 0;    /* use for exclued points */
 
704
                        for (i = 0; i < numpnt; i++)
 
705
                        {
 
706
                                sp.point = PackSeqPntGet(pspp, i);
 
707
 
 
708
                                if (SeqLocOffset(seq_loc, &vn, &range, offset))
 
709
                                {
 
710
                                        intcnt++;
 
711
                                        PackSeqPntPut(pspp2, range.left);
 
712
                                }
 
713
                                else
 
714
                                        othercnt++;
 
715
                        }
 
716
                        if (! intcnt)  /* no points in region */
 
717
                        {
 
718
                                PackSeqPntFree(pspp2);
 
719
                                break;
 
720
                        }
 
721
 
 
722
                        if (rev)  /* rev comp */
 
723
                        {
 
724
                                pspp = pspp2;
 
725
                                pspp2 = PackSeqPntNew();
 
726
                                numpnt = PackSeqPntNum(pspp);
 
727
                                numpnt--;
 
728
                                for (i = numpnt; i >= 0; i--)    /* reverse order */
 
729
                                {
 
730
                                        tpos = PackSeqPntGet(pspp, i);
 
731
                                        PackSeqPntPut(pspp2, tpos);
 
732
                                }
 
733
                                PackSeqPntFree(pspp);
 
734
                        }
 
735
                        pspp2->id = SeqIdDup(newid);
 
736
                        pspp2->strand = the_strand;
 
737
                        pspp2->fuzz = ReMapIntFuzz(pspp->fuzz, rev, seq_loc, head, offset);
 
738
 
 
739
                        newhead = ValNodeNew(NULL);
 
740
                        newhead->choice = SEQLOC_PACKED_PNT;
 
741
                        newhead->data.ptrvalue = (Pointer)pspp2;
 
742
            break;
 
743
        case SEQLOC_WHOLE:    /* whole */
 
744
                        newhead = ValNodeNew(NULL);
 
745
                        sip2 = SeqIntNew();
 
746
                        sip2->id = SeqIdDup(newid);
 
747
                        sip2->from = range.left;
 
748
                        sip2->to = range.right;
 
749
                        sip2->strand = range.strand;
 
750
                        if (range.r_trunc)
 
751
                        {
 
752
                                ifp = IntFuzzNew();
 
753
                                ifp->choice = 4;   /* lim */
 
754
                                ifp->a = 1;        /* greater than */
 
755
                                sip2->if_to = ifp;
 
756
                        }
 
757
 
 
758
                        if (range.l_trunc)
 
759
                        {
 
760
                                ifp = IntFuzzNew();
 
761
                                ifp->choice = 4;   /* lim */
 
762
                                ifp->a = 2;        /* less than */
 
763
                                sip2->if_from = ifp;
 
764
                        }
 
765
 
 
766
                        newhead->choice = SEQLOC_INT;
 
767
                        newhead->data.ptrvalue = (Pointer)sip2;
 
768
                        break;
 
769
        case SEQLOC_PNT:    /* pnt */
 
770
                        spp = (SeqPntPtr)(head->data.ptrvalue);
 
771
 
 
772
                        spp2 = SeqPntNew();
 
773
                        spp2->id = SeqIdDup(newid);
 
774
                        spp2->point = range.left;
 
775
                        spp2->strand = range.strand;
 
776
                        spp2->fuzz = ReMapIntFuzz(spp->fuzz, rev, seq_loc, head, offset);
 
777
 
 
778
                        newhead = ValNodeNew(NULL);
 
779
                        newhead->choice = SEQLOC_PNT;
 
780
                        newhead->data.ptrvalue = (Pointer)spp2;
 
781
            break;
 
782
        case SEQLOC_INT:    /* int */
 
783
                        sip = (SeqIntPtr)(head->data.ptrvalue);
 
784
 
 
785
                        sip2 = SeqIntNew();
 
786
                        sip2->id = SeqIdDup(newid);
 
787
                        sip2->strand = range.strand;
 
788
                        sip2->from = range.left;
 
789
                        sip2->to = range.right;
 
790
 
 
791
                        if (rev)  /* reverse ends if seq_loc on complement */
 
792
                        {
 
793
                                ifp1 = sip->if_to;
 
794
                                ifp2 = sip->if_from;
 
795
                        }
 
796
                        else
 
797
                        {
 
798
                                ifp1 = sip->if_from;
 
799
                                ifp2 = sip->if_to;
 
800
                        }
 
801
 
 
802
 
 
803
                        if (range.r_trunc)
 
804
                        {
 
805
                                ifp = IntFuzzNew();
 
806
                                ifp->choice = 4;   /* lim */
 
807
                                ifp->a = 1;        /* greater than */
 
808
                                sip2->if_to = ifp;
 
809
                        }
 
810
                        else
 
811
                        {
 
812
                                sip2->if_to = ReMapIntFuzz(ifp2, rev, seq_loc, head, offset);
 
813
                        }
 
814
 
 
815
                        if (range.l_trunc)
 
816
                        {
 
817
                                ifp = IntFuzzNew();
 
818
                                ifp->choice = 4;   /* lim */
 
819
                                ifp->a = 2;        /* less than */
 
820
                                sip2->if_from = ifp;
 
821
                        }
 
822
                        else
 
823
                        {
 
824
                                sip2->if_from = ReMapIntFuzz(ifp1, rev, seq_loc, head, offset);
 
825
                        }
 
826
 
 
827
                        newhead = ValNodeNew(NULL);
 
828
                        newhead->choice = SEQLOC_INT;
 
829
                        newhead->data.ptrvalue = (Pointer)sip2;
 
830
            break;
 
831
        case SEQLOC_BOND:   /* bond -- 2 seqs */
 
832
                        sbp2 = NULL;
 
833
                        sbp = (SeqBondPtr)(head->data.ptrvalue);
 
834
                        vn.choice = SEQLOC_PNT;
 
835
                        vn.data.ptrvalue = sbp->a;
 
836
                        vn.next = NULL;
 
837
                        tmp = SeqLocReMap (newid, seq_loc, (SeqLocPtr)(&vn), offset, rev);
 
838
                        if (tmp != NULL)
 
839
                        {
 
840
                                sbp2 = SeqBondNew();
 
841
                                sbp2->a = (SeqPntPtr)(tmp->data.ptrvalue);
 
842
                                MemFree(tmp);
 
843
                        }
 
844
                        if (sbp->b != NULL)
 
845
                        {
 
846
                                vn.data.ptrvalue = sbp->b;
 
847
                                tmp = SeqLocReMap (newid, seq_loc, (SeqLocPtr)(&vn), offset, rev);
 
848
                                if (tmp != NULL)
 
849
                                {
 
850
                                        if (sbp2 == NULL)
 
851
                                        {
 
852
                                                sbp2 = SeqBondNew();
 
853
                                                sbp2->a = (SeqPntPtr)(tmp->data.ptrvalue);
 
854
                                        }
 
855
                                        else
 
856
                                                sbp2->b = (SeqPntPtr)(tmp->data.ptrvalue);
 
857
                                        MemFree(tmp);
 
858
                                }
 
859
                        }
 
860
                        if (sbp2 != NULL)
 
861
                        {
 
862
                                newhead = ValNodeNew(NULL);
 
863
                                newhead->choice = SEQLOC_BOND;
 
864
                                newhead->data.ptrvalue = sbp2;
 
865
                        }
 
866
                        break;
 
867
        case SEQLOC_FEAT:   /* feat -- can't track yet */
 
868
        case SEQLOC_NULL:    /* NULL */
 
869
        case SEQLOC_EMPTY:    /* empty */
 
870
                        break;
 
871
        case SEQLOC_EQUIV:    /* does it stay equiv? */
 
872
                    was_equiv = TRUE;
 
873
        case SEQLOC_MIX:    /* mix -- more than one seq */
 
874
        case SEQLOC_PACKED_INT:    /* packed int */
 
875
                        prev = NULL;
 
876
                        thead = NULL;
 
877
                        dropped_first = FALSE;
 
878
                        dropped_last = FALSE;
 
879
                        for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
 
880
                        {
 
881
                                next = slp->next;
 
882
                                if (slp->choice == SEQLOC_NULL)   /* special case */
 
883
                                {
 
884
                                        tmp = NULL;
 
885
                                        if ((prev != NULL) && (next != NULL))
 
886
                                        {
 
887
                                                if (prev->choice != SEQLOC_NULL)
 
888
                                                {
 
889
                                                        tmp = ValNodeNew(NULL);
 
890
                                                        tmp->choice = SEQLOC_NULL;
 
891
                                                }
 
892
                                        }
 
893
                                }
 
894
                                else
 
895
                                        tmp = SeqLocReMap (newid, seq_loc, slp, offset, rev);
 
896
                                if (tmp != NULL)
 
897
                                {
 
898
                                        dropped_last = FALSE;
 
899
                                        if (prev != NULL)
 
900
                                        {
 
901
                                                if ((prev->choice == SEQLOC_INT) && (tmp->choice == SEQLOC_INT))
 
902
                                                {
 
903
                                                        sip = (SeqIntPtr)(prev->data.ptrvalue);
 
904
                                                        sip2 = (SeqIntPtr)(tmp->data.ptrvalue);
 
905
 
 
906
                                                        if ((sip->strand == Seq_strand_minus) &&
 
907
                                                                (sip2->strand == Seq_strand_minus))
 
908
                                                        {
 
909
                                                                if (sip->from == (sip2->to + 1))
 
910
                                                                {
 
911
                                                                        sip->from = sip2->from;
 
912
                                                                        sip->if_from = sip2->if_from;
 
913
                                                                        sip2->if_from = NULL;
 
914
                                                                        tmp = SeqLocFree(tmp);
 
915
                                                                }
 
916
                                                        }
 
917
                                                        else if((sip->strand != Seq_strand_minus) &&
 
918
                                                                (sip2->strand != Seq_strand_minus))
 
919
                                                        {
 
920
                                                                if (sip->to == (sip2->from - 1))
 
921
                                                                {
 
922
                                                                        sip->to = sip2->to;
 
923
                                                                        sip->if_to = sip2->if_to;
 
924
                                                                        sip2->if_to = NULL;
 
925
                                                                        tmp = SeqLocFree(tmp);
 
926
                                                                }
 
927
                                                        }
 
928
                                                }
 
929
                                                else if ((prev->choice == SEQLOC_NULL) && (tmp->choice == SEQLOC_NULL))
 
930
                                                {
 
931
                                                        tmp = SeqLocFree(tmp);
 
932
                                                }
 
933
                                        }
 
934
                                        else if (tmp->choice == SEQLOC_NULL)
 
935
                                        {
 
936
                                                tmp = SeqLocFree(tmp);
 
937
                                        }
 
938
 
 
939
                                        if (tmp != NULL)   /* still have one? */
 
940
                                        {
 
941
                                                if (prev != NULL)
 
942
                                                        prev->next = tmp;
 
943
                                                else
 
944
                                                        thead = tmp;
 
945
                                                prev = tmp;
 
946
                                        }
 
947
                                }
 
948
                                else
 
949
                                {
 
950
                                        if (prev == NULL)
 
951
                                                dropped_first = TRUE;
 
952
                                        else
 
953
                                                dropped_last = TRUE;
 
954
                                }
 
955
                        }
 
956
                        if (prev != NULL)
 
957
                        {
 
958
                                if (prev->choice == SEQLOC_NULL)  /* ends with NULL */
 
959
                                {
 
960
                                        prev = NULL;
 
961
                                        for (slp = thead; slp->next != NULL; slp = slp->next)
 
962
                                                prev = slp;
 
963
                                        if (prev != NULL)
 
964
                                        {
 
965
                                                prev->next = NULL;
 
966
                                                SeqLocFree(slp);
 
967
                                        }
 
968
                                        else
 
969
                                        {
 
970
                                                thead = SeqLocFree(thead);
 
971
                                        }
 
972
                                }
 
973
                        }
 
974
                        if (thead != NULL)
 
975
                        {
 
976
                                intcnt = 0;
 
977
                                othercnt = 0;
 
978
                                for (slp = thead; slp != NULL; slp = slp->next)
 
979
                                {
 
980
                                        if (slp->choice == SEQLOC_INT)
 
981
                                                intcnt++;
 
982
                                        else
 
983
                                                othercnt++;
 
984
                                }
 
985
                                if ((intcnt + othercnt) > 1)
 
986
                                {
 
987
                                        newhead = ValNodeNew(NULL);
 
988
                                        if (head->choice == SEQLOC_EQUIV)
 
989
                                                newhead->choice = SEQLOC_EQUIV;
 
990
                                        else
 
991
                                        {
 
992
                                                if (othercnt == 0)
 
993
                                                        newhead->choice = SEQLOC_PACKED_INT;
 
994
                                                else
 
995
                                                        newhead->choice = SEQLOC_MIX;
 
996
                                        }
 
997
 
 
998
                                        rev = FALSE; /* KLUDGE: turn off reordering */
 
999
                                        if (! rev)
 
1000
                                                newhead->data.ptrvalue = (Pointer)thead;
 
1001
                                        else                            /* reverse order */
 
1002
                                        {
 
1003
                                                tmp = NULL;
 
1004
                                                while (thead != NULL)
 
1005
                                                {
 
1006
                                                        prev = NULL;
 
1007
                                                        for (slp = thead; slp->next != NULL; slp = slp->next)
 
1008
                                                                prev = slp;
 
1009
                                                        if (prev != NULL)
 
1010
                                                                prev->next = NULL;
 
1011
                                                        else
 
1012
                                                                thead = NULL;
 
1013
                                                        if (tmp != NULL)
 
1014
                                                                tmp->next = slp;
 
1015
                                                        else
 
1016
                                                                newhead->data.ptrvalue = (Pointer)slp;
 
1017
                                                        slp->next = NULL;
 
1018
                                                        tmp = slp;
 
1019
                                                }
 
1020
 
 
1021
                                        }
 
1022
                                }
 
1023
                                else                 /* only one SeqLoc left */
 
1024
                                        newhead = thead;
 
1025
 
 
1026
                                if ((! was_equiv) && ((dropped_first) || (dropped_last)))
 
1027
                                {                       /* add Int_fuzz when intervals are dropped */
 
1028
                                        if (rev)
 
1029
                                        {
 
1030
                                                was_equiv = dropped_first;
 
1031
                                                dropped_first = dropped_last;
 
1032
                                                dropped_last = was_equiv;
 
1033
                                        }
 
1034
 
 
1035
                                        slp = NULL;
 
1036
                                        tmp = NULL;
 
1037
                                        while ((slp = SeqLocFindNext(newhead, slp)) != NULL)
 
1038
                                        {
 
1039
                                                if ((tmp == NULL) && (dropped_first))   /* first one */
 
1040
                                                {
 
1041
                                                        switch (slp->choice)
 
1042
                                                        {
 
1043
                                                                case SEQLOC_INT:
 
1044
                                                                        ifp = IntFuzzNew();
 
1045
                                                                        ifp->choice = 4;   /* lim */
 
1046
                                                                        ifp->a = 2;        /* assume lt */
 
1047
                                                                        sip = (SeqIntPtr)(slp->data.ptrvalue);
 
1048
                                                                        if (sip->strand != Seq_strand_minus)
 
1049
                                                                        {
 
1050
                                                                                sip->if_from = IntFuzzFree(sip->if_from);
 
1051
                                                                                sip->if_from = ifp;
 
1052
                                                                        }
 
1053
                                                                        else
 
1054
                                                                        {
 
1055
                                                                                sip->if_to = IntFuzzFree(sip->if_to);
 
1056
                                                                                sip->if_to = ifp;
 
1057
                                                                                ifp->a = 1;   /* gt */
 
1058
                                                                        }
 
1059
                                                                        break;
 
1060
                                                                default:
 
1061
                                                                        break;
 
1062
                                                        }
 
1063
                                                }
 
1064
                                                tmp = slp;
 
1065
                                        }
 
1066
 
 
1067
                                        if ((tmp != NULL) && (dropped_last))
 
1068
                                        {
 
1069
                                                switch (tmp->choice)
 
1070
                                                {
 
1071
                                                        case SEQLOC_INT:
 
1072
                                                                ifp = IntFuzzNew();
 
1073
                                                                ifp->choice = 4;   /* lim */
 
1074
                                                                ifp->a = 1;        /* assume gt */
 
1075
                                                                sip = (SeqIntPtr)(tmp->data.ptrvalue);
 
1076
                                                                if (sip->strand != Seq_strand_minus)
 
1077
                                                                {
 
1078
                                                                        sip->if_from = IntFuzzFree(sip->if_from);
 
1079
                                                                        sip->if_from = ifp;
 
1080
                                                                }
 
1081
                                                                else
 
1082
                                                                {
 
1083
                                                                        sip->if_to = IntFuzzFree(sip->if_to);
 
1084
                                                                        sip->if_to = ifp;
 
1085
                                                                        ifp->a = 2;   /* lt */
 
1086
                                                                }
 
1087
                                                                break;
 
1088
                                                        default:
 
1089
                                                                break;
 
1090
                                                }
 
1091
                                        }
 
1092
                                }
 
1093
 
 
1094
                        }
 
1095
            break;
 
1096
        default:
 
1097
            break;
 
1098
 
 
1099
        }
 
1100
        return newhead;
 
1101
}
 
1102
 
 
1103
        /** citttype is currently 0, or 1=OBJ_SEQFEAT_CIT **/
 
1104
 
 
1105
static Boolean NEAR GatherPub(InternalGCCPtr gccp, ValNodePtr vnp,
 
1106
        Uint1 cittype, Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
 
1107
{
 
1108
        GatherContextPtr gcp;
 
1109
        GatherScopePtr gsp;
 
1110
        Boolean takeit;
 
1111
        Int2 LocateItem = 0;
 
1112
        Pointer LocateData = NULL;
 
1113
        Uint1 thistype;
 
1114
 
 
1115
        if (vnp == NULL) return TRUE;
 
1116
 
 
1117
        gcp = &(gccp->gc);
 
1118
        gsp = &(gccp->scope);
 
1119
 
 
1120
        if (cittype)
 
1121
                thistype = OBJ_SEQFEAT_CIT;
 
1122
        else
 
1123
                thistype = OBJ_PUB;
 
1124
 
 
1125
        if (gsp->ignore[thistype])
 
1126
                return TRUE;
 
1127
 
 
1128
        takeit = in_scope;
 
1129
 
 
1130
        if (gccp->locatetype == thistype)
 
1131
        {
 
1132
                LocateItem = gccp->locateID;
 
1133
                LocateData = gccp->locatePtr;
 
1134
        }
 
1135
 
 
1136
        gcp->parentitem = tparent;
 
1137
        gcp->parenttype = ttype;
 
1138
 
 
1139
        gccp->itemIDs[thistype]++;
 
1140
 
 
1141
        if (LocateItem == gccp->itemIDs[thistype])
 
1142
                takeit = TRUE;
 
1143
        if (LocateData == (Pointer)vnp)
 
1144
                takeit = TRUE;
 
1145
        if (takeit)
 
1146
        {
 
1147
                gcp->itemID = gccp->itemIDs[thistype];
 
1148
                gcp->thisitem = (Pointer)vnp;
 
1149
                gcp->thistype = thistype;
 
1150
                gcp->prevlink = prevlink;
 
1151
                GatherAddToStack(gcp);
 
1152
                if (! (*(gccp->userfunc))(gcp))
 
1153
                        return FALSE;
 
1154
                if (LocateItem) return FALSE;
 
1155
                if (LocateData != NULL) return FALSE;
 
1156
        }
 
1157
 
 
1158
        return TRUE;
 
1159
}
 
1160
 
 
1161
static Boolean NEAR GatherPubSet(InternalGCCPtr gccp, ValNodePtr vnp,
 
1162
        Uint1 cittype, Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
 
1163
{
 
1164
        GatherContextPtr gcp;
 
1165
        GatherScopePtr gsp;
 
1166
        Boolean takeit;
 
1167
        Int2 LocateItem = 0;
 
1168
        Pointer LocateData = NULL;
 
1169
        Uint1 thistype;
 
1170
        ValNodePtr vnp2;
 
1171
 
 
1172
        if (vnp == NULL) return TRUE;
 
1173
 
 
1174
        gcp = &(gccp->gc);
 
1175
        gsp = &(gccp->scope);
 
1176
 
 
1177
        if (gsp->ignore[OBJ_PUB_SET])
 
1178
                return TRUE;
 
1179
 
 
1180
        takeit = in_scope;
 
1181
 
 
1182
        if (gccp->locatetype == OBJ_PUB_SET)
 
1183
        {
 
1184
                LocateItem = gccp->locateID;
 
1185
                LocateData = gccp->locatePtr;
 
1186
        }
 
1187
 
 
1188
        gcp->previtem = NULL;
 
1189
        gcp->prevtype = OBJ_PUB_SET;
 
1190
        gcp->parentitem = tparent;
 
1191
        gcp->parenttype = ttype;
 
1192
        thistype = OBJ_PUB_SET;
 
1193
 
 
1194
        gccp->itemIDs[OBJ_PUB_SET]++;
 
1195
        if (LocateItem == gccp->itemIDs[OBJ_PUB_SET])
 
1196
                takeit = TRUE;
 
1197
        if (LocateData == (Pointer)vnp)
 
1198
                takeit = TRUE;
 
1199
 
 
1200
        gcp->itemID = gccp->itemIDs[OBJ_PUB_SET];
 
1201
        gcp->thisitem = (Pointer)vnp;
 
1202
        gcp->thistype = thistype;
 
1203
        GatherAddToStack(gcp);
 
1204
 
 
1205
        if (takeit)
 
1206
        {
 
1207
                gcp->prevlink = prevlink;
 
1208
                if (! (*(gccp->userfunc))(gcp))
 
1209
                        return FALSE;
 
1210
                if (LocateItem) return FALSE;
 
1211
                if (LocateData != NULL) return FALSE;
 
1212
        }
 
1213
 
 
1214
        gcp->indent++;
 
1215
        prevlink = &(vnp->data.ptrvalue);
 
1216
        gcp->previtem = NULL;
 
1217
        gcp->prevtype = OBJ_PUB;
 
1218
 
 
1219
        for (vnp2 = (ValNodePtr)(vnp->data.ptrvalue); vnp2 != NULL; vnp2 = vnp2->next)
 
1220
        {
 
1221
                if (! GatherPub(gccp, vnp2, cittype, thistype, (Pointer)vnp,
 
1222
                                                    prevlink, in_scope))
 
1223
                        return FALSE;
 
1224
                prevlink = (Pointer PNTR)&(vnp2->next);
 
1225
                gcp->previtem = (Pointer)vnp2;
 
1226
        
 
1227
        }
 
1228
        gcp->indent--;
 
1229
 
 
1230
        return TRUE;
 
1231
}
 
1232
 
 
1233
static Boolean NEAR GatherSeqIds(InternalGCCPtr gccp, SeqIdPtr sip,
 
1234
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
 
1235
{
 
1236
        GatherContextPtr gcp;
 
1237
        GatherScopePtr gsp;
 
1238
        Boolean takeit;
 
1239
        Int2 LocateItem = 0;
 
1240
        Pointer LocateData = NULL;
 
1241
        Uint1 thistype;
 
1242
 
 
1243
        if (sip == NULL) return TRUE;
 
1244
 
 
1245
        gcp = &(gccp->gc);
 
1246
        gsp = &(gccp->scope);
 
1247
 
 
1248
        if (gsp->ignore[OBJ_SEQID])
 
1249
                return TRUE;
 
1250
 
 
1251
        if (gccp->locatetype == OBJ_SEQID)
 
1252
        {
 
1253
                LocateItem = gccp->locateID;
 
1254
                LocateData = gccp->locatePtr;
 
1255
        }
 
1256
        else
 
1257
                takeit = TRUE;
 
1258
 
 
1259
        gcp->previtem = NULL;
 
1260
        gcp->prevtype = OBJ_SEQID;
 
1261
        gcp->parentitem = tparent;
 
1262
        gcp->parenttype = ttype;
 
1263
        thistype = OBJ_SEQID;
 
1264
 
 
1265
        while (sip != NULL)
 
1266
        {
 
1267
                gccp->itemIDs[OBJ_SEQID]++;
 
1268
                if (LocateItem == gccp->itemIDs[OBJ_SEQID])
 
1269
                        takeit = TRUE;
 
1270
                if (LocateData == (Pointer)sip)
 
1271
                        takeit = TRUE;
 
1272
                if (takeit)
 
1273
                {
 
1274
                        gcp->itemID = gccp->itemIDs[OBJ_SEQID];
 
1275
                        gcp->thisitem = (Pointer)sip;
 
1276
                        gcp->thistype = thistype;
 
1277
                        gcp->prevlink = prevlink;
 
1278
                        GatherAddToStack(gcp);
 
1279
                        if (! (*(gccp->userfunc))(gcp))
 
1280
                                return FALSE;
 
1281
                        if (LocateItem) return FALSE;
 
1282
                        if (LocateData != NULL) return FALSE;
 
1283
                }
 
1284
 
 
1285
                gcp->previtem = (Pointer)sip;
 
1286
                prevlink = (Pointer PNTR)&(sip->next);
 
1287
                sip = sip->next;
 
1288
        }
 
1289
 
 
1290
        return TRUE;
 
1291
}
 
1292
 
 
1293
static Boolean NEAR GatherSeqDescr(InternalGCCPtr gccp, ValNodePtr vnp,
 
1294
       Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
 
1295
{
 
1296
        GatherContextPtr gcp;
 
1297
        GatherScopePtr gsp;
 
1298
        Boolean takeit;
 
1299
        Int2 LocateItem = 0;
 
1300
        Pointer LocateData = NULL;
 
1301
        Uint1 thistype;
 
1302
 
 
1303
        if (vnp == NULL) return TRUE;
 
1304
 
 
1305
        gcp = &(gccp->gc);
 
1306
        gsp = &(gccp->scope);
 
1307
 
 
1308
        if (gsp->ignore[OBJ_SEQDESC])
 
1309
                return TRUE;
 
1310
 
 
1311
        if (gccp->locatetype == OBJ_SEQDESC)
 
1312
        {
 
1313
                LocateItem = gccp->locateID;
 
1314
                LocateData = gccp->locatePtr;
 
1315
        }
 
1316
 
 
1317
        if ((LocateItem) || (LocateData != NULL))   /* fetching an item */
 
1318
        {
 
1319
                takeit = FALSE;
 
1320
        }
 
1321
        else
 
1322
        {
 
1323
                takeit = in_scope;       /* if ! in_scope don't take it */
 
1324
                if (gccp->bsp != NULL)   /* gsp->target set a Bioseq */
 
1325
                {
 
1326
                        if (tparent != (Pointer)(gccp->bsp))
 
1327
                        {
 
1328
                                if (! ObjMgrIsChild(tparent, (Pointer)(gccp->bsp)))
 
1329
                                        takeit = FALSE;   /* not in propagation path */
 
1330
                                else
 
1331
                                        gcp->propagated = TRUE;
 
1332
                        }
 
1333
                }
 
1334
        }
 
1335
 
 
1336
        gcp->previtem = NULL;
 
1337
        gcp->prevtype = OBJ_SEQDESC;
 
1338
        gcp->parentitem = tparent;
 
1339
        gcp->parenttype = ttype;
 
1340
        thistype = OBJ_SEQDESC;
 
1341
 
 
1342
        while (vnp != NULL)
 
1343
        {
 
1344
                gccp->itemIDs[OBJ_SEQDESC]++;
 
1345
                if (LocateItem == gccp->itemIDs[OBJ_SEQDESC])
 
1346
                        takeit = TRUE;
 
1347
                if (LocateData == (Pointer)vnp)
 
1348
                        takeit = TRUE;
 
1349
                if (takeit)
 
1350
                {
 
1351
                        gcp->itemID = gccp->itemIDs[OBJ_SEQDESC];
 
1352
                        gcp->thisitem = (Pointer)vnp;
 
1353
                        gcp->thistype = thistype;
 
1354
                        gcp->prevlink = prevlink;
 
1355
                        GatherAddToStack(gcp);
 
1356
                        if (! (*(gccp->userfunc))(gcp))
 
1357
                                return FALSE;
 
1358
                        if (LocateItem) return FALSE;
 
1359
                        if (LocateData != NULL) return FALSE;
 
1360
                }
 
1361
 
 
1362
                gcp->previtem = (Pointer)vnp;
 
1363
                prevlink = (Pointer PNTR)&(vnp->next);
 
1364
                vnp = vnp->next;
 
1365
        }
 
1366
        gcp->propagated = FALSE;   /* reset propagated flag */
 
1367
 
 
1368
        return TRUE;
 
1369
}
 
1370
 
 
1371
 
 
1372
static Int4 get_site_offset(SeqLocPtr slp, SeqLocPtr head, Int4 r_len)
 
1373
{
 
1374
        Uint1 m_strand, s_strand;
 
1375
 
 
1376
        m_strand = SeqLocStrand(slp);
 
1377
        s_strand = SeqLocStrand(slp);
 
1378
 
 
1379
        if(m_strand == 0 || s_strand ==0)
 
1380
                return 0;
 
1381
        if(m_strand == 3 || s_strand == 3)
 
1382
                return 0;
 
1383
 
 
1384
        if(m_strand == s_strand)
 
1385
                return 0;
 
1386
 
 
1387
        if(m_strand == Seq_strand_plus && s_strand == Seq_strand_minus)
 
1388
                return (-r_len);
 
1389
        else
 
1390
                return r_len;
 
1391
}
 
1392
 
 
1393
 
 
1394
static Boolean process_packed_pnt(SeqLocPtr slp, SeqLocPtr head, Int4 r_len, Int4 offset, GatherContextPtr gcp, Int2Ptr max_interval)
 
1395
{
 
1396
        PackSeqPntPtr pspp;
 
1397
        Int4 site;
 
1398
        Int4 site_offset;       /*for treating restriction site as an interval*/
 
1399
        Int2 index;
 
1400
        Int4 m_start, m_stop;
 
1401
        Uint1 m_strand;
 
1402
        Int4 min, max;
 
1403
        Boolean rev;
 
1404
        Int4 pos, ctr, i;
 
1405
        GatherRangePtr trdp, lrdp;
 
1406
        GatherRange trange;
 
1407
        Boolean is_end = FALSE;
 
1408
 
 
1409
        if(head->choice !=SEQLOC_PACKED_PNT)
 
1410
                return FALSE;
 
1411
 
 
1412
        if(!SeqIdForSameBioseq(SeqLocId(slp), SeqLocId(head)))
 
1413
                return FALSE;
 
1414
        m_strand = SeqLocStrand(slp);
 
1415
        site_offset = get_site_offset(slp, head, (r_len-1));
 
1416
        rev = (SeqLocStrand(slp) == Seq_strand_minus);
 
1417
        lrdp = gcp->rdp;
 
1418
 
 
1419
 
 
1420
        m_start = SeqLocStart(slp);
 
1421
        m_stop = SeqLocStop(slp);
 
1422
        pspp = head->data.ptrvalue;
 
1423
        site =0;
 
1424
        index =0;
 
1425
        min = -1;
 
1426
        max = -1;
 
1427
        ctr = 0;
 
1428
        while( !is_end && ((site = PackSeqPntGet(pspp, index))!= -1))
 
1429
        {
 
1430
                ++index;
 
1431
                if (ctr >= (*max_interval))
 
1432
                {
 
1433
                        trdp = lrdp;
 
1434
                        lrdp = (GatherRangePtr)MemNew((size_t)((*max_interval + 20) * sizeof(GatherRange)));
 
1435
                        MemCopy(lrdp, trdp, (size_t)(*max_interval * sizeof(GatherRange)));
 
1436
                        MemFree(trdp);
 
1437
                        *max_interval += 20;
 
1438
                        gcp->rdp = lrdp;
 
1439
                }
 
1440
                is_end = (site > m_stop);
 
1441
                if(site >= m_start && site <=m_stop)
 
1442
                {
 
1443
                        site += site_offset;
 
1444
                        if(rev)
 
1445
                                pos = offset + (m_stop - site);
 
1446
                        else
 
1447
                                pos = offset + (site - m_start);
 
1448
                        if(max == -1)
 
1449
                        {
 
1450
                                max = pos;
 
1451
                                min = pos;
 
1452
                        }
 
1453
                        else
 
1454
                        {
 
1455
                                max = MAX(pos, max);
 
1456
                                min = MIN(pos, min);
 
1457
                        }
 
1458
                        lrdp[ctr].left = pos;
 
1459
                        lrdp[ctr].right = pos;
 
1460
                        lrdp[ctr].l_trunc = FALSE;
 
1461
                        lrdp[ctr].r_trunc = FALSE;
 
1462
                        lrdp[ctr].strand = m_strand;
 
1463
                        ++ctr;
 
1464
                }
 
1465
        }
 
1466
 
 
1467
        if (ctr)     /* got some */
 
1468
        {
 
1469
                gcp->extremes.left = min;
 
1470
                gcp->extremes.right = max;
 
1471
                gcp->extremes.l_trunc = FALSE;
 
1472
                gcp->extremes.r_trunc = FALSE;
 
1473
                gcp->extremes.strand = m_strand;
 
1474
 
 
1475
                gcp->num_interval = (Int2)ctr;
 
1476
                if (rev)    /* reverse order on rev location */
 
1477
                {
 
1478
                        i = 0;
 
1479
                        ctr--;
 
1480
                        while (i < ctr)
 
1481
                        {
 
1482
                                MemCopy(&trange, &(lrdp[i]), sizeof(GatherRange));
 
1483
                                MemCopy(&(lrdp[i]), &(lrdp[ctr]), sizeof(GatherRange));
 
1484
                                MemCopy(&(lrdp[ctr]), &trange, sizeof(GatherRange));
 
1485
                                i++; ctr++;
 
1486
                        }
 
1487
                }
 
1488
                return TRUE;
 
1489
        }
 
1490
        else
 
1491
                return FALSE;
 
1492
}
 
1493
 
 
1494
/* functions to speed up targeted feature gather by using seqmgr explore index */
 
1495
 
 
1496
static ObjMgrDataPtr GatherGetOmdpForBioseq (BioseqPtr bsp)
 
1497
 
 
1498
{
 
1499
  ObjMgrDataPtr  omdp;
 
1500
  ObjMgrPtr      omp;
 
1501
 
 
1502
  if (bsp == NULL) return NULL;
 
1503
  omdp = (ObjMgrDataPtr) bsp->omdp;
 
1504
  if (omdp != NULL) return omdp;
 
1505
  omp = ObjMgrWriteLock ();
 
1506
  omdp = ObjMgrFindByData (omp, bsp);
 
1507
  ObjMgrUnlock ();
 
1508
  bsp->omdp = (Pointer) omdp;
 
1509
  return omdp;
 
1510
}
 
1511
 
 
1512
static SeqFeatPtr LIBCALL SeqMgrGetNextFeatureByID (BioseqPtr bsp, SeqFeatPtr curr,
 
1513
                                                    Uint1 seqFeatChoice, Uint1 featDefChoice,
 
1514
                                                    SeqMgrFeatContext PNTR context)
 
1515
 
 
1516
{
 
1517
  BioseqExtraPtr      bspextra;
 
1518
  Uint2               entityID;
 
1519
  SMFeatItemPtr PNTR  featsByID;
 
1520
  Uint2               i;
 
1521
  SMFeatItemPtr       item;
 
1522
  ObjMgrDataPtr       omdp;
 
1523
  Uint1               seqfeattype;
 
1524
 
 
1525
  if (context == NULL) return NULL;
 
1526
 
 
1527
  if (curr == NULL) {
 
1528
    if (bsp == NULL) return NULL;
 
1529
    omdp = GatherGetOmdpForBioseq (bsp);
 
1530
    if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
 
1531
 
 
1532
    context->omdp = (Pointer) omdp;
 
1533
    context->index = 0;
 
1534
  }
 
1535
 
 
1536
  omdp = (ObjMgrDataPtr) context->omdp;
 
1537
  if (omdp == NULL) return NULL;
 
1538
  bspextra = (BioseqExtraPtr) omdp->extradata;
 
1539
  if (bspextra == NULL) return NULL;
 
1540
  featsByID = bspextra->featsByID;
 
1541
  if (featsByID == NULL || bspextra->numfeats < 1) return NULL;
 
1542
 
 
1543
  entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
 
1544
 
 
1545
  i = context->index;
 
1546
 
 
1547
  while (i < bspextra->numfeats) {
 
1548
    item = featsByID [i];
 
1549
    if (item != NULL) {
 
1550
      curr = item->sfp;
 
1551
      i++;
 
1552
      if (curr != NULL) {
 
1553
        seqfeattype = curr->data.choice;
 
1554
        if ((seqFeatChoice == 0 || seqfeattype == seqFeatChoice) &&
 
1555
            (featDefChoice == 0 || item->subtype == featDefChoice) &&
 
1556
            (! item->ignore)) {
 
1557
          context->entityID = entityID;
 
1558
          context->itemID = item->itemID;
 
1559
          context->sfp = curr;
 
1560
          context->sap = item->sap;
 
1561
          context->bsp = item->bsp;
 
1562
          context->label = item->label;
 
1563
          context->left = item->left;
 
1564
          context->right = item->right;
 
1565
          context->dnaStop = item->dnaStop;
 
1566
          context->partialL = item->partialL;
 
1567
          context->partialR = item->partialR;
 
1568
          context->farloc = item->farloc;
 
1569
          context->strand = item->strand;
 
1570
          context->seqfeattype = seqfeattype;
 
1571
          context->featdeftype = item->subtype;
 
1572
          context->numivals = item->numivals;
 
1573
          context->ivals = item->ivals;
 
1574
          context->userdata = NULL;
 
1575
          context->omdp = (Pointer) omdp;
 
1576
          context->index = i;
 
1577
          return curr;
 
1578
        }
 
1579
      }
 
1580
    }
 
1581
  }
 
1582
 
 
1583
  return NULL;
 
1584
}
 
1585
 
 
1586
static Boolean NEAR ExploreSeqFeat (
 
1587
  InternalGCCPtr gccp,
 
1588
  BioseqPtr bsp,
 
1589
  Boolean in_scope
 
1590
)
 
1591
 
 
1592
{
 
1593
  SeqMgrFeatContext  fcontext;
 
1594
  GatherContextPtr   gcp;
 
1595
  GatherScopePtr     gsp;
 
1596
  SeqFeatPtr         sfp;
 
1597
  Boolean            takecit;
 
1598
  ValNodePtr         vnp;
 
1599
 
 
1600
  /* gccp->locatetype is known to be NULL if target used */
 
1601
 
 
1602
  if (gccp == NULL || bsp == NULL) return TRUE;
 
1603
 
 
1604
  gcp = &(gccp->gc);
 
1605
  gsp = &(gccp->scope);
 
1606
 
 
1607
  if (gsp->ignore [OBJ_SEQFEAT]) return TRUE;
 
1608
  if (gsp->ignore [OBJ_SEQFEAT_CIT]) {
 
1609
    takecit = FALSE;
 
1610
  } else {
 
1611
    takecit = TRUE;
 
1612
  }
 
1613
 
 
1614
  gcp->num_interval = 0;
 
1615
 
 
1616
  if (gsp->get_feats_location) {
 
1617
    sfp = SeqMgrGetNextFeatureByID (bsp, NULL, 0, 0, &fcontext);
 
1618
    while (sfp != NULL) {
 
1619
 
 
1620
      gcp->previtem = NULL;
 
1621
      gcp->prevtype = OBJ_SEQFEAT;
 
1622
 
 
1623
      gcp->parentitem = sfp->idx.parentptr;
 
1624
      gcp->parenttype = sfp->idx.parenttype;
 
1625
 
 
1626
      gcp->itemID = sfp->idx.itemID;
 
1627
      gcp->thisitem = (Pointer) sfp;
 
1628
      gcp->thistype = OBJ_SEQFEAT;
 
1629
      gcp->prevlink = sfp->idx.prevlink;
 
1630
 
 
1631
      gcp->product = FALSE;
 
1632
 
 
1633
      GatherAddToStack (gcp);
 
1634
      if (! (*(gccp->userfunc)) (gcp)) return FALSE;
 
1635
 
 
1636
      if (sfp->cit != NULL && takecit) {
 
1637
        if (! GatherPubSet (gccp, sfp->cit, 1, OBJ_SEQFEAT, (Pointer) sfp,
 
1638
                            (Pointer PNTR) &(sfp->cit), in_scope))
 
1639
          return FALSE;
 
1640
      }
 
1641
 
 
1642
      sfp = SeqMgrGetNextFeatureByID (bsp, sfp, 0, 0, &fcontext);
 
1643
    }
 
1644
  }
 
1645
 
 
1646
  if (gsp->get_feats_product) {
 
1647
    for (vnp = SeqMgrGetSfpProductList (bsp); vnp != NULL; vnp = vnp->next) {
 
1648
      sfp = (SeqFeatPtr) vnp->data.ptrvalue;
 
1649
      if (sfp != NULL) {
 
1650
 
 
1651
        gcp->previtem = NULL;
 
1652
        gcp->prevtype = OBJ_SEQFEAT;
 
1653
 
 
1654
        gcp->parentitem = sfp->idx.parentptr;
 
1655
        gcp->parenttype = sfp->idx.parenttype;
 
1656
 
 
1657
        gcp->itemID = sfp->idx.itemID;
 
1658
        gcp->thisitem = (Pointer) sfp;
 
1659
        gcp->thistype = OBJ_SEQFEAT;
 
1660
        gcp->prevlink = sfp->idx.prevlink;
 
1661
 
 
1662
        gcp->product = TRUE;
 
1663
 
 
1664
        GatherAddToStack (gcp);
 
1665
        if (! (*(gccp->userfunc)) (gcp)) return FALSE;
 
1666
 
 
1667
        if (sfp->cit != NULL && takecit) {
 
1668
          if (! GatherPubSet (gccp, sfp->cit, 1, OBJ_SEQFEAT, (Pointer) sfp,
 
1669
                              (Pointer PNTR) &(sfp->cit), in_scope))
 
1670
            return FALSE;
 
1671
        }
 
1672
      }
 
1673
    }
 
1674
  }
 
1675
 
 
1676
  /* ignoring sfp->cit on non-targeted records, not keeping counter in synch */
 
1677
 
 
1678
  return TRUE;
 
1679
}
 
1680
 
 
1681
static Boolean NEAR GatherSeqFeat(InternalGCCPtr gccp, SeqFeatPtr sfp,
 
1682
           Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Uint1 sfptype)
 
1683
{
 
1684
        GatherContextPtr gcp;
 
1685
        GatherScopePtr gsp;
 
1686
        Boolean takeit=TRUE,
 
1687
                takecit, checkseq=FALSE;
 
1688
        SeqLocPtr slp, head, tslp, target[2];
 
1689
        GatherRangePtr rdp, trdp, lrdp;
 
1690
        Int4 offset, totlen, left_end;
 
1691
        Boolean rev, revs[2];
 
1692
        Int2 ctr, max_interval, i, numcheck, j;
 
1693
        GatherRange trange;
 
1694
        Int2 LocateItem = 0;
 
1695
        Pointer LocateData = NULL;
 
1696
        Uint1 thistype;
 
1697
        Boolean is_packed_pnt = FALSE;  /*is the seq-loc a packed point?*/
 
1698
        Boolean stop_now, convert_loc = FALSE;
 
1699
        SeqIdPtr newid;
 
1700
        CdRegionPtr cdr;
 
1701
        CodeBreakPtr cbp;
 
1702
        RnaRefPtr rrp;
 
1703
        tRNAPtr trp;
 
1704
 
 
1705
 
 
1706
        SeqFeatPtr prevsfp = NULL;
 
1707
 
 
1708
        if (sfp == NULL) return TRUE;
 
1709
 
 
1710
        gcp = &(gccp->gc);
 
1711
        gsp = &(gccp->scope);
 
1712
 
 
1713
        if (gsp->ignore[sfptype])
 
1714
                return TRUE;
 
1715
 
 
1716
        if (gccp->locatetype == sfptype)
 
1717
        {
 
1718
                LocateItem = gccp->locateID;
 
1719
                LocateData = gccp->locatePtr;
 
1720
        }
 
1721
        else
 
1722
                LocateItem = 0;
 
1723
 
 
1724
        if (gsp->target != NULL)
 
1725
        {
 
1726
                checkseq = TRUE;
 
1727
                numcheck = 1;
 
1728
                target[0] = gsp->target;
 
1729
                revs[0] = gccp->rev;
 
1730
                if (gccp->segloc != NULL)
 
1731
                {
 
1732
                        numcheck = 2;
 
1733
                        target[1] = gccp->segloc;
 
1734
                        revs[1] = FALSE;
 
1735
                }
 
1736
                rdp = &(gcp->extremes);
 
1737
                offset = gsp->offset;
 
1738
                max_interval = gccp->max_interval;
 
1739
                lrdp = gcp->rdp;
 
1740
 
 
1741
                convert_loc = gsp->convert_loc;
 
1742
                newid = gsp->newid;
 
1743
        }
 
1744
 
 
1745
        if (gsp->ignore[OBJ_SEQFEAT_CIT])
 
1746
                takecit = FALSE;
 
1747
        else
 
1748
                takecit = TRUE;
 
1749
 
 
1750
        gcp->prevtype = sfptype;
 
1751
        gcp->parentitem = tparent;
 
1752
        gcp->parenttype = ttype;
 
1753
        gcp->num_interval = 0;
 
1754
        thistype = sfptype;
 
1755
 
 
1756
        while (sfp != NULL)
 
1757
        {
 
1758
                gcp->previtem = (Pointer) prevsfp;
 
1759
                gccp->itemIDs[sfptype]++;
 
1760
                if (LocateItem == gccp->itemIDs[sfptype])
 
1761
                        in_scope = TRUE;
 
1762
                if (LocateData == (Pointer)sfp)
 
1763
                        in_scope = TRUE;
 
1764
 
 
1765
                gcp->itemID = gccp->itemIDs[sfptype];
 
1766
                takeit = TRUE;
 
1767
                stop_now = FALSE;
 
1768
 
 
1769
                if (in_scope)
 
1770
                {
 
1771
                        gcp->thisitem = (Pointer)sfp;
 
1772
                        gcp->thistype = thistype;
 
1773
                        gcp->prevlink = prevlink;
 
1774
                        gcp->product = FALSE;
 
1775
                        head = sfp->location;
 
1776
                        if (checkseq)    /* find by SeqLoc overlap */
 
1777
                        {
 
1778
                                takeit = FALSE;
 
1779
                                is_packed_pnt = (head->choice == SEQLOC_PACKED_PNT);
 
1780
                                for (j = 0; ((j < numcheck) && (! takeit) && (!stop_now)); j++)
 
1781
                                {
 
1782
                                        slp = target[j];
 
1783
                                        rev = revs[j];
 
1784
                                        if (gsp->get_feats_location)
 
1785
                                        {
 
1786
                                                if(is_packed_pnt)
 
1787
                                                {
 
1788
                                                        if(process_packed_pnt(slp, head, 0, offset, gcp, &(gccp->max_interval)))
 
1789
                                                        {
 
1790
                                                                takeit = TRUE;
 
1791
                                                                stop_now= TRUE;
 
1792
                                                        }
 
1793
                                                }
 
1794
                                                else
 
1795
                                                        takeit = SeqLocOffset(slp, head, rdp, offset);
 
1796
                                        }
 
1797
 
 
1798
                                        if ((! takeit) && (gsp->get_feats_product))
 
1799
                                        {
 
1800
                                                head = sfp->product;
 
1801
                                                takeit = SeqLocOffset(slp, head, rdp, offset);
 
1802
                                                if (takeit)
 
1803
                                                        gcp->product = TRUE;
 
1804
                                        }
 
1805
 
 
1806
                                        if ((takeit) && (! gsp->nointervals) && (!stop_now))  /* map intervals in loc */
 
1807
                                        {
 
1808
                                                tslp = NULL;
 
1809
                                                ctr = 0;
 
1810
                                                while ((tslp = SeqLocFindNext(head, tslp)) != NULL)
 
1811
                                                {
 
1812
                                                        if (ctr >= max_interval)
 
1813
                                                        {
 
1814
                                                                trdp = lrdp;
 
1815
                                                                lrdp = (GatherRangePtr)MemNew((size_t)((max_interval + 20) * sizeof(GatherRange)));
 
1816
                                                                MemCopy(lrdp, trdp, (size_t)(max_interval * sizeof(GatherRange)));
 
1817
                                                                MemFree(trdp);
 
1818
                                                                max_interval += 20;
 
1819
                                                                gccp->max_interval = max_interval;
 
1820
                                                                gcp->rdp = lrdp;
 
1821
                                                        }
 
1822
                                                        if (SeqLocOffset(slp, tslp, &(lrdp[ctr]), offset))
 
1823
                                                                ctr++;
 
1824
                                                }
 
1825
                                                if (ctr)     /* got some */
 
1826
                                                {
 
1827
                                                        gcp->num_interval = ctr;
 
1828
                                                        if (rev)    /* reverse order on rev location */
 
1829
                                                        {
 
1830
                                                                i = 0;
 
1831
                                                                ctr--;
 
1832
                                                                while (i < ctr)
 
1833
                                                                {
 
1834
                                                                        MemCopy(&trange, &(lrdp[i]), sizeof(GatherRange));
 
1835
                                                                        MemCopy(&(lrdp[i]), &(lrdp[ctr]), sizeof(GatherRange));
 
1836
                                                                        MemCopy(&(lrdp[ctr]), &trange, sizeof(GatherRange));
 
1837
                                                                        i++; ctr--;
 
1838
                                                                }
 
1839
                                                        }
 
1840
                                                }
 
1841
                                        }
 
1842
 
 
1843
                                        if ((takeit) && (convert_loc) && (! stop_now)) /* convert SeqLoc */
 
1844
                                        {
 
1845
                                                gcp->new_loc = SeqLocReMap(newid, slp, head, offset, rev);
 
1846
                                                if (gsp->get_feats_location)
 
1847
                                                {
 
1848
                                                        gcp->extra_loc_cnt = 0;
 
1849
                                                        if (sfp->data.choice == SEQFEAT_CDREGION)
 
1850
                                                        {
 
1851
                                                                cdr = (CdRegionPtr)(sfp->data.value.ptrvalue);
 
1852
                                                                for (cbp = cdr->code_break; cbp != NULL;
 
1853
                                                                                cbp = cbp->next)
 
1854
                                                                {
 
1855
                                                                        tslp = SeqLocReMap(newid, slp, cbp->loc, offset, rev);
 
1856
                                                                        GatherAddExtraLoc(gcp, tslp);
 
1857
                                                                }
 
1858
                                                        }
 
1859
                                                        else if (sfp->data.choice == SEQFEAT_RNA)
 
1860
                                                        {
 
1861
                                                                rrp = (RnaRefPtr)(sfp->data.value.ptrvalue);
 
1862
                                                                if ((rrp->ext.choice == 2) && 
 
1863
                                                                        (rrp->ext.value.ptrvalue != NULL)) /* tRNA */
 
1864
                                                                {
 
1865
                                                                        trp = (tRNAPtr)(rrp->ext.value.ptrvalue);
 
1866
                                                                        if (trp->anticodon != NULL)
 
1867
                                                                        {
 
1868
                                                                                tslp = SeqLocReMap(newid, slp, trp->anticodon,
 
1869
                                                                                        offset, rev);
 
1870
                                                                                GatherAddExtraLoc(gcp, tslp);
 
1871
                                                                        }
 
1872
                                                                }
 
1873
                                                        }
 
1874
                                                }
 
1875
                                        }
 
1876
                                }
 
1877
                        }
 
1878
 
 
1879
                        if (takeit)
 
1880
                        {
 
1881
                                if (gccp->segcnt)    /* which segment was it in? */
 
1882
                                {
 
1883
                                        left_end = offset;
 
1884
                                        for (i = 0; i < gccp->segcnt; i++)
 
1885
                                        {
 
1886
                                                totlen = left_end + gccp->seglens[i];
 
1887
                                                if ((rdp->left >= left_end) && (rdp->left < totlen))
 
1888
                                                        gccp->found_annot[i] = TRUE;
 
1889
                                                else if ((rdp->right >= left_end) && (rdp->right < totlen))
 
1890
                                                        gccp->found_annot[i] = TRUE;
 
1891
                                                left_end = totlen;
 
1892
                                        }       
 
1893
                                }
 
1894
 
 
1895
                                GatherAddToStack(gcp);
 
1896
                                if (! (*(gccp->userfunc))(gcp))
 
1897
                                        return FALSE;
 
1898
                                if (LocateItem) return FALSE;
 
1899
                                if (LocateData != NULL) return FALSE;
 
1900
 
 
1901
                                if ((sfp->cit != NULL) && (takecit))
 
1902
                                {
 
1903
                                        if (! GatherPubSet(gccp, sfp->cit, 1, thistype, (Pointer)sfp,
 
1904
                                                                                (Pointer PNTR)&(sfp->cit), in_scope))
 
1905
                                                return FALSE;
 
1906
 
 
1907
                                        gcp->prevtype = thistype;
 
1908
                                        gcp->parentitem = tparent;
 
1909
                                        gcp->parenttype = ttype;
 
1910
                                }
 
1911
                        }
 
1912
                }
 
1913
                else /* out of scope */
 
1914
                {
 
1915
 
 
1916
                        if (sfp->cit != NULL)  /* just run the counter */
 
1917
                        {
 
1918
                                if (! GatherPubSet(gccp, sfp->cit, 1, thistype, (Pointer)sfp,
 
1919
                                                                        (Pointer PNTR)&(sfp->cit), in_scope))
 
1920
                                        return FALSE;
 
1921
 
 
1922
                                gcp->prevtype = thistype;
 
1923
                                gcp->parentitem = tparent;
 
1924
                                gcp->parenttype = ttype;
 
1925
                        }
 
1926
                }
 
1927
 
 
1928
                prevsfp = sfp;
 
1929
                prevlink = (Pointer PNTR)&(sfp->next);
 
1930
                sfp = sfp->next;
 
1931
        }
 
1932
        return TRUE;
 
1933
}
 
1934
 
 
1935
static Uint1 align_strand_get(Uint1Ptr strands, Int2 order)
 
1936
{
 
1937
        if(strands == NULL)
 
1938
                return 0;
 
1939
        else
 
1940
                return strands[order];
 
1941
}
 
1942
 
 
1943
static Boolean check_reverse_strand(Uint1 loc_strand, Uint1 a_strand)
 
1944
{
 
1945
        if(loc_strand == Seq_strand_minus || a_strand == Seq_strand_minus)
 
1946
                return (loc_strand != a_strand);
 
1947
        return FALSE;
 
1948
 
 
1949
}
 
1950
 
 
1951
/****************************************************************************
 
1952
***
 
1953
*       get_align_ends(): map the two ends of the alignment
 
1954
*
 
1955
*****************************************************************************
 
1956
***/
 
1957
 
 
1958
static void load_start_stop(Int4Ptr start, Int4Ptr stop, Int4 c_start, Int4 c_stop)
 
1959
{
 
1960
        if(*start == -1)
 
1961
        {
 
1962
                *start = c_start;
 
1963
                *stop = c_stop;
 
1964
        }
 
1965
        else
 
1966
        {
 
1967
                *start = MIN(*start, c_start);
 
1968
                *stop = MAX(*stop, c_stop);
 
1969
        }
 
1970
}
 
1971
 
 
1972
static Int2 get_master_order(SeqIdPtr ids, SeqIdPtr sip)
 
1973
{
 
1974
        Int2 i;
 
1975
        
 
1976
        for(i =0; ids!=NULL; ids = ids->next, ++i)
 
1977
        {
 
1978
                if(SeqIdForSameBioseq(ids, sip))
 
1979
                        return i;
 
1980
        }
 
1981
        return -1;
 
1982
}
 
1983
 
 
1984
NLM_EXTERN Boolean get_align_ends(SeqAlignPtr align, SeqIdPtr id, 
 
1985
                                  Int4Ptr start, Int4Ptr stop, Uint1Ptr strand)
 
1986
{
 
1987
    Int2 i, n;
 
1988
    Boolean is_found;
 
1989
    Int4 c_start, c_stop;
 
1990
    DenseSegPtr dsp;
 
1991
    DenseDiagPtr ddp;
 
1992
    StdSegPtr ssp;
 
1993
    SeqLocPtr loc;
 
1994
    SeqAlignPtr sap;
 
1995
 
 
1996
    *start = -1;
 
1997
    *stop = -1;
 
1998
    switch(align->segtype) {
 
1999
    case 5: /* Discontinuous alignment */
 
2000
        
 
2001
        sap = (SeqAlignPtr)(align->segs);
 
2002
        
 
2003
        for(; sap != NULL; sap = sap->next) {
 
2004
            if(!get_align_ends(sap, id, &c_start, &c_stop, strand))
 
2005
                return FALSE;
 
2006
            load_start_stop(start, stop, c_start, c_stop);
 
2007
        }
 
2008
        return (*start != -1);
 
2009
        
 
2010
    case 2:         /*DenseSeg*/
 
2011
        dsp = (DenseSegPtr)(align->segs);
 
2012
        if(id == NULL)
 
2013
            i =0;
 
2014
        else {
 
2015
            i = get_master_order(dsp->ids, id);
 
2016
            if( i == -1)
 
2017
                return FALSE;
 
2018
        }
 
2019
        
 
2020
        for(n =0; n<dsp->numseg; ++n) {
 
2021
            c_start = dsp->starts[n*(dsp->dim) +i];
 
2022
            if(c_start != -1) { /*check for a non-gapped region*/
 
2023
                c_stop = c_start + dsp->lens[n] -1;
 
2024
                load_start_stop(start, stop, c_start, c_stop);
 
2025
            }
 
2026
        }
 
2027
        *strand = align_strand_get(dsp->strands, i);
 
2028
        return (*start != -1);
 
2029
        
 
2030
    case 3:
 
2031
        ssp = (StdSegPtr)(align->segs);
 
2032
        while(ssp) {
 
2033
            is_found = FALSE;
 
2034
            for (loc = ssp->loc; loc!=NULL && !is_found; loc=loc->next) {
 
2035
                if(loc->choice != SEQLOC_EMPTY) {
 
2036
                    if(id == NULL)
 
2037
                        is_found = TRUE;
 
2038
                    else
 
2039
                        
 
2040
                        is_found=SeqIdForSameBioseq(SeqLocId(loc), id);
 
2041
                    if(is_found) {
 
2042
                        load_start_stop(start, stop, SeqLocStart(loc), SeqLocStop(loc));
 
2043
                        *strand = SeqLocStrand(loc);
 
2044
                    }
 
2045
                }
 
2046
            }
 
2047
            ssp = ssp->next;
 
2048
        }
 
2049
        return (*start != -1);
 
2050
        
 
2051
    case 1:
 
2052
        ddp = (DenseDiagPtr)(align->segs);
 
2053
        while(ddp) {
 
2054
            if(id == NULL)
 
2055
                i =0;
 
2056
            else
 
2057
                i = get_master_order(ddp->id, id);
 
2058
            if(i != -1) {
 
2059
                c_start = ddp->starts[i];
 
2060
                c_stop = ddp->starts[i] + ddp->len -1;
 
2061
                *strand = align_strand_get(ddp->strands, i);
 
2062
                load_start_stop(start, stop, c_start, c_stop);
 
2063
            }
 
2064
            ddp = ddp->next;
 
2065
        }                       
 
2066
        return (*start != -1);
 
2067
        
 
2068
    default:
 
2069
        return FALSE;
 
2070
    }
 
2071
}
 
2072
        
 
2073
                                
 
2074
static void LinkAlignData(AlignDataPtr PNTR head, AlignDataPtr adp)
 
2075
{
 
2076
        AlignDataPtr curr;
 
2077
        
 
2078
        if(*head == NULL)
 
2079
                *head = adp;
 
2080
        else
 
2081
        {
 
2082
                curr = *head;
 
2083
                while(curr->next != NULL)
 
2084
                        curr = curr->next;
 
2085
                curr->next = adp;
 
2086
        }
 
2087
}
 
2088
 
 
2089
static void LinkAlignRangeToAlignData(AlignDataPtr adp, AlignRangePtr arp)
 
2090
{
 
2091
        
 
2092
        if(arp == NULL)
 
2093
                return;
 
2094
        if(adp->arp  == NULL)
 
2095
                adp->arp = arp;
 
2096
        else
 
2097
                adp->last->next = arp;
 
2098
        adp->last = arp;
 
2099
}
 
2100
 
 
2101
static AlignDataPtr get_adp_node(AlignDataPtr head, Int2 order, Uint2 chain)
 
2102
{
 
2103
        if(head == NULL)
 
2104
                return NULL;
 
2105
        while(head)
 
2106
        {
 
2107
                if(head->order == order && head->chain == chain)
 
2108
                        return head;
 
2109
                head = head->next;
 
2110
        }
 
2111
        return NULL;
 
2112
}
 
2113
 
 
2114
 
 
2115
 
 
2116
static void load_align_data(AlignDataPtr PNTR head, Int4 start, Int4 stop, Uint1 strand, SeqIdPtr sip, Boolean rev, Int2 seg_type, GatherRange t_range, Boolean ck_interval, Int2 order, Uint2 chain)
 
2117
{
 
2118
        AlignDataPtr adp;
 
2119
        AlignRangePtr arp;
 
2120
        Int4 left, right;
 
2121
        
 
2122
        adp = get_adp_node(*head, order, chain);
 
2123
        if(rev)
 
2124
        {
 
2125
                if(strand == Seq_strand_minus)
 
2126
                        strand = Seq_strand_plus;
 
2127
                else
 
2128
                        strand = Seq_strand_minus;
 
2129
        }
 
2130
        if(adp == NULL)
 
2131
        {
 
2132
                adp = MemNew(sizeof(AlignData));
 
2133
                adp->chain= chain;
 
2134
                adp->order = order;
 
2135
                adp->sip = sip;
 
2136
                MemCopy((&adp->extremes), &t_range, sizeof(GatherRange));
 
2137
                adp->extremes.strand = strand;
 
2138
                if(seg_type != GAP_SEG)
 
2139
                {
 
2140
                        adp->seqends.start = start;
 
2141
                        adp->seqends.stop = stop;
 
2142
                }
 
2143
                else
 
2144
                {
 
2145
                        adp->seqends.start = -1;
 
2146
                        adp->seqends.stop = -1;
 
2147
                }
 
2148
                adp->seqends.strand = strand;
 
2149
                adp->arp = NULL;
 
2150
                adp->next = NULL;
 
2151
                LinkAlignData(head, adp);
 
2152
        }
 
2153
        else
 
2154
        {
 
2155
            left = adp->extremes.left;
 
2156
            right = adp->extremes.right;
 
2157
            if(t_range.left < left)
 
2158
            {
 
2159
                adp->extremes.left = t_range.left;
 
2160
                adp->extremes.l_trunc = t_range.l_trunc;
 
2161
            }
 
2162
            if(t_range.right > right)
 
2163
            {
 
2164
                adp->extremes.right = t_range.right;
 
2165
                adp->extremes.r_trunc = t_range.r_trunc;
 
2166
            }
 
2167
            if(seg_type != GAP_SEG)
 
2168
            {
 
2169
                if(adp->seqends.start == -1)
 
2170
                {
 
2171
                        adp->seqends.start = start;
 
2172
                        adp->seqends.stop = stop;
 
2173
                }
 
2174
                else
 
2175
                {
 
2176
                        adp->seqends.start = MIN(start, adp->seqends.start);
 
2177
                        adp->seqends.stop = MAX(stop, adp->seqends.stop);
 
2178
                }
 
2179
            }
 
2180
        }       
 
2181
                
 
2182
                
 
2183
        if(ck_interval)
 
2184
        {
 
2185
                arp = MemNew(sizeof(AlignRange));
 
2186
                arp->segtype = (Uint1)seg_type;
 
2187
                MemCopy(&(arp->gr), &t_range, sizeof(GatherRange));
 
2188
                arp->sr.start = start;
 
2189
                arp->sr.stop = stop;
 
2190
                arp->sr.strand = strand;
 
2191
                LinkAlignRangeToAlignData(adp, arp);
 
2192
        }
 
2193
}
 
2194
 
 
2195
 
 
2196
static Boolean get_end_diag_val(DenseSegPtr dsp, Int2 m_order, Int2 k_seg, Int4Ptr start, Int4Ptr stop, Boolean first)
 
2197
{
 
2198
        Int2 i, k;
 
2199
        Int2 dim;
 
2200
        Boolean increase = TRUE;
 
2201
 
 
2202
        dim = dsp->dim;
 
2203
        if(first)
 
2204
                k = k_seg;
 
2205
        else
 
2206
                k = dsp->numseg-1 -k_seg;
 
2207
 
 
2208
        increase = (k ==0);
 
2209
                
 
2210
        for(i =0; i<dsp->numseg; ++i)
 
2211
        {
 
2212
                if(dsp->starts[dim*k+m_order] != -1)
 
2213
                {
 
2214
                        *start = dsp->starts[dim*k+m_order];
 
2215
                        *stop = *start + dsp->lens[k] -1;
 
2216
                        return TRUE;
 
2217
                }
 
2218
                if(increase)
 
2219
                        ++k;
 
2220
                else
 
2221
                        --k;
 
2222
        }
 
2223
        return FALSE;
 
2224
}
 
2225
 
 
2226
static void load_trunc_info(SeqLocPtr slp, GatherRangePtr grp)
 
2227
{
 
2228
        SeqIntPtr sint;
 
2229
        Boolean f_trunc = FALSE, t_trunc = FALSE;
 
2230
        IntFuzzPtr ifp;
 
2231
 
 
2232
        if(slp == NULL || grp == NULL)
 
2233
                return;
 
2234
        if(slp->choice != SEQLOC_INT)
 
2235
                return;
 
2236
        sint = slp->data.ptrvalue;
 
2237
        if(sint != NULL)
 
2238
        {
 
2239
                ifp = sint->if_from;
 
2240
                if(ifp)
 
2241
                {
 
2242
                        if(ifp->choice == 4 && ifp->a == 2)
 
2243
                                f_trunc = TRUE;
 
2244
                }
 
2245
                ifp = sint->if_to;
 
2246
                if(ifp)
 
2247
                {
 
2248
                        if(ifp->choice == 4 && ifp->a == 1)
 
2249
                                t_trunc = TRUE;
 
2250
                }
 
2251
        }
 
2252
        
 
2253
        grp->l_trunc = f_trunc;
 
2254
        grp->r_trunc = t_trunc;
 
2255
        if(grp->strand != sint->strand)
 
2256
        {
 
2257
                if(grp->strand == Seq_strand_minus || sint->strand == Seq_strand_minus)
 
2258
                {
 
2259
                        grp->l_trunc = t_trunc;
 
2260
                        grp->r_trunc = f_trunc;
 
2261
                }
 
2262
        }
 
2263
}
 
2264
 
 
2265
/**************************************************************
 
2266
*
 
2267
*
 
2268
**************************************************************/
 
2269
 
 
2270
static Boolean is_end_gaps_for_master(DenseSegPtr dsp, Int2 m_order, Int2 k_seg, Int2 j_seg, Boolean left)
 
2271
{
 
2272
        Int2 i, k;
 
2273
        Boolean is_gap = FALSE;
 
2274
        Boolean increase;
 
2275
 
 
2276
        /*get the first non-gap segment*/
 
2277
        if(left)
 
2278
                k = k_seg;
 
2279
        else
 
2280
                k = dsp->numseg-1 - k_seg;
 
2281
        increase = (k ==0);
 
2282
        for(i = 0; i<dsp->numseg; ++i)
 
2283
        {
 
2284
                if(dsp->starts[(dsp->dim)*k+m_order] != -1)
 
2285
                        return FALSE;
 
2286
                else
 
2287
                {
 
2288
                        if(j_seg == k)
 
2289
                                return TRUE;
 
2290
                }
 
2291
                if(increase)
 
2292
                        ++k;
 
2293
                else
 
2294
                        --k;
 
2295
        }
 
2296
 
 
2297
        return FALSE;
 
2298
}
 
2299
 
 
2300
static Uint1 get_master_strand_for_continous_ssp (StdSegPtr ssp, SeqIdPtr m_sip)
 
2301
{
 
2302
        SeqLocPtr loc;
 
2303
 
 
2304
        while(ssp)
 
2305
        {
 
2306
                for(loc= ssp->loc; loc!=NULL; loc = loc->next)
 
2307
                {
 
2308
                        if(SeqIdMatch(SeqLocId(loc), m_sip))
 
2309
                        {
 
2310
                                if(loc->choice != SEQLOC_EMPTY)
 
2311
                                        return SeqLocStrand(loc);
 
2312
                        }
 
2313
                }
 
2314
 
 
2315
                ssp = ssp->next;
 
2316
        }
 
2317
 
 
2318
        return 0;
 
2319
}
 
2320
 
 
2321
static Int2 get_ssp_numseg (StdSegPtr ssp)
 
2322
{
 
2323
        Int2 i = 0;
 
2324
 
 
2325
        while(ssp)
 
2326
        {
 
2327
                ++i;
 
2328
                ssp = ssp->next;
 
2329
        }
 
2330
 
 
2331
        return i;
 
2332
}
 
2333
 
 
2334
static StdSegPtr get_nth_ssp (StdSegPtr ssp, Int2 order)
 
2335
{
 
2336
        Int2 i;
 
2337
 
 
2338
        i = 0;
 
2339
        while(ssp)
 
2340
        {
 
2341
                if(i == order)
 
2342
                        return ssp;
 
2343
                ++i;
 
2344
                ssp = ssp->next;
 
2345
        }
 
2346
 
 
2347
        return NULL;
 
2348
}
 
2349
 
 
2350
static Boolean is_fuzz_loc (SeqLocPtr slp)
 
2351
{
 
2352
        SeqLocPtr t_slp;
 
2353
        SeqIntPtr sint;
 
2354
        SeqPntPtr spp;
 
2355
 
 
2356
        t_slp = NULL;
 
2357
        while((t_slp = SeqLocFindNext(slp, t_slp)) != NULL)
 
2358
        {
 
2359
                if(t_slp->choice == SEQLOC_INT)
 
2360
                {
 
2361
                        sint = t_slp->data.ptrvalue;
 
2362
                        if(sint->if_from || sint->if_to)
 
2363
                                return TRUE;
 
2364
                }
 
2365
                else if(t_slp->choice == SEQLOC_PNT)
 
2366
                {
 
2367
                        spp = t_slp->data.ptrvalue;
 
2368
                        if(spp->fuzz)
 
2369
                                return TRUE;
 
2370
                }
 
2371
        }
 
2372
 
 
2373
        return FALSE;
 
2374
}
 
2375
                        
 
2376
static Int4 calculate_mag_val (StdSegPtr ssp, SeqIdPtr m_sip, BoolPtr inverse)
 
2377
{
 
2378
        SeqLocPtr m_slp, s_slp;
 
2379
        SeqLocPtr slp;
 
2380
        Int4 mag_val;
 
2381
 
 
2382
        while(ssp)
 
2383
        {
 
2384
                m_slp = NULL;
 
2385
                s_slp = NULL;
 
2386
                for(slp = ssp->loc; slp != NULL; slp = slp->next)
 
2387
                {
 
2388
                        if(SeqIdMatch(SeqLocId(slp), m_sip))
 
2389
                                m_slp = slp;
 
2390
                        else
 
2391
                                s_slp = slp;
 
2392
                }
 
2393
 
 
2394
                if(m_slp && s_slp && SeqLocLen(m_slp) && SeqLocLen(s_slp))
 
2395
                {
 
2396
                        if(!is_fuzz_loc(m_slp) && !is_fuzz_loc(s_slp))
 
2397
                        {
 
2398
                                if(SeqLocLen(m_slp) > SeqLocLen(s_slp))
 
2399
                                {
 
2400
                                        mag_val = SeqLocLen(m_slp)/SeqLocLen(s_slp);
 
2401
                                        if(SeqLocLen(m_slp)%SeqLocLen(s_slp) == 0)
 
2402
                                        {
 
2403
                                                *inverse = FALSE;
 
2404
                                                return mag_val;
 
2405
                                        }
 
2406
                                }
 
2407
                                else
 
2408
                                {
 
2409
                                        mag_val = SeqLocLen(s_slp)/SeqLocLen(m_slp);
 
2410
                                        if(SeqLocLen(s_slp)%SeqLocLen(m_slp) == 0)
 
2411
                                        {
 
2412
                                                *inverse = TRUE;
 
2413
                                                return mag_val;
 
2414
                                        }
 
2415
                                }
 
2416
                        }
 
2417
                }
 
2418
 
 
2419
                ssp = ssp->next;
 
2420
        }
 
2421
 
 
2422
 
 
2423
        return -1;
 
2424
}
 
2425
 
 
2426
static Int4 modify_offset (SeqLocPtr m_loc, SeqLocPtr s_loc, Int4 m_offset, Int4Ptr left_over)
 
2427
{
 
2428
        Int4 m_len, s_len;
 
2429
 
 
2430
        *left_over = 0;
 
2431
        if(m_offset == 0)
 
2432
                return 0;
 
2433
        else
 
2434
        {
 
2435
                m_len = SeqLocLen(m_loc);
 
2436
                s_len = SeqLocLen(s_loc);
 
2437
                if(m_len == s_len)
 
2438
                        return m_offset;
 
2439
                else
 
2440
                {
 
2441
                        if(m_len/s_len == 3)
 
2442
                        {
 
2443
                                *left_over = m_offset%3;
 
2444
                                if(*left_over > 0)
 
2445
                                        *left_over = 3 - (*left_over);
 
2446
                        }
 
2447
                        if(*left_over > 0)
 
2448
                                return ((m_offset * s_len) /m_len + 1);
 
2449
                        else
 
2450
                                return ((m_offset * s_len) /m_len);
 
2451
                }
 
2452
        }
 
2453
}
 
2454
 
 
2455
static Uint1 get_DenseSeg_strand(DenseSegPtr dsp, Int2 order)
 
2456
{
 
2457
        Int2 i, dim;
 
2458
 
 
2459
        if(dsp == NULL || dsp->strands == NULL)
 
2460
                return 0;
 
2461
        dim = dsp->dim;
 
2462
        for(i = 0; i<dsp->numseg; ++i)
 
2463
        {
 
2464
                if(dsp->starts[dim * i + order] != -1)
 
2465
                        return (dsp->strands[dim*i + order]);
 
2466
        }
 
2467
 
 
2468
        return 0;
 
2469
}
 
2470
 
 
2471
NLM_EXTERN AlignDataPtr gather_align_data(SeqLocPtr m_slp, SeqAlignPtr align, 
 
2472
                                          Int4 offset, Boolean ck_interval, 
 
2473
                                          Boolean map)
 
2474
{
 
2475
    SeqIdPtr m_sip, sip;
 
2476
    Uint1 m_strand, strand, c_strand;
 
2477
    DenseSegPtr dsp;
 
2478
    StdSegPtr ssp;
 
2479
    DenseDiagPtr ddp;
 
2480
    Int2 i, m_order, k, numseg, t_numseg;
 
2481
    Int4 s1;
 
2482
    Uint1 seg_type;
 
2483
    Boolean is_found = FALSE;
 
2484
    Int4 start, stop, c_start, c_stop;
 
2485
    Int4 m_start, m_stop;
 
2486
    Int4 master_pos;    /*position of the master sequence*/
 
2487
    Int4 off_start, off_stop;
 
2488
    Boolean rev;
 
2489
    GatherRange gr, t_range;
 
2490
    SeqLocPtr a_slp, loc;
 
2491
    AlignDataPtr head = NULL, curr;
 
2492
    Uint2 chain;
 
2493
    Int4 h_start, h_stop;
 
2494
    Boolean inc_left_mgap;      /*include the left gaps on the master sequence*/
 
2495
    Boolean inc_right_mgap;     /*include the right gaps on the master sequence*/
 
2496
    Boolean left_end_gap, right_end_gap;
 
2497
    Int2 k_seg;
 
2498
    Boolean collect;
 
2499
    Boolean load;
 
2500
    Boolean cont;       /*is it a continous segment ? */
 
2501
    Int4 len;
 
2502
    Int4 mag_val;       /*the magnification value */
 
2503
    SeqLocPtr master_loc, m_loc;
 
2504
    Boolean inverse;
 
2505
    Int4 leftover;
 
2506
    Int4 left, right;
 
2507
    Boolean use_stop;
 
2508
    Uint1 ma_strand;
 
2509
    SeqAlignPtr sap;
 
2510
 
 
2511
    strand = 0;
 
2512
    m_sip = SeqLocId(m_slp);
 
2513
    if(!get_align_ends(align, m_sip, &start, &stop, &c_strand))
 
2514
        return NULL;
 
2515
    
 
2516
    a_slp = SeqLocIntNew(start, stop, c_strand, m_sip);
 
2517
    if(!SeqLocOffset(m_slp, a_slp, &gr, offset)) {
 
2518
        SeqLocFree(a_slp);
 
2519
        return NULL;
 
2520
    }
 
2521
    cont = FALSE;
 
2522
    if(align->segtype == 2)
 
2523
        cont = TRUE;
 
2524
    else if(align->segtype == 3) {
 
2525
        cont = (align->type == 3);
 
2526
        /* cont = TRUE; */
 
2527
        ssp = align->segs;
 
2528
        mag_val = calculate_mag_val (ssp, m_sip, &inverse);
 
2529
        if(mag_val == -1) {
 
2530
            mag_val = 1;
 
2531
            inverse = FALSE;
 
2532
        }
 
2533
    }
 
2534
    
 
2535
    m_strand = SeqLocStrand(m_slp);
 
2536
    m_start = SeqLocStart(m_slp);
 
2537
    m_stop = SeqLocStop(m_slp);
 
2538
    c_start = -1;
 
2539
    c_stop =-1;
 
2540
 
 
2541
    switch(align->segtype) {
 
2542
 
 
2543
    case 5: /* Discontinuous alignment */
 
2544
        for(sap = (SeqAlignPtr) align->segs; sap != NULL; sap = sap->next) {
 
2545
            curr =  gather_align_data(m_slp, sap, offset, ck_interval, map);
 
2546
            LinkAlignData(&head, curr);
 
2547
        }
 
2548
        break;
 
2549
 
 
2550
    case 2: /*for DenseSegs*/
 
2551
        dsp = (DenseSegPtr)(align->segs);
 
2552
        m_order = get_master_order(dsp->ids, m_sip);
 
2553
        ma_strand = get_DenseSeg_strand(dsp, m_order);
 
2554
        rev = check_reverse_strand(m_strand, c_strand);
 
2555
        if(rev)
 
2556
            k = dsp->numseg -1;
 
2557
        else
 
2558
            k =0;
 
2559
        k_seg = k;
 
2560
        
 
2561
        get_end_diag_val(dsp, m_order, k, &h_start, &h_stop, TRUE);
 
2562
        if(!(h_stop < m_start || h_start > m_stop))     /*it is within the range*/
 
2563
            inc_left_mgap = TRUE;
 
2564
        else
 
2565
            inc_left_mgap = FALSE;
 
2566
        
 
2567
        get_end_diag_val(dsp, m_order, k, &h_start, &h_stop, FALSE);
 
2568
        if(!(h_stop < m_start || h_start > m_stop))     /*it is within the range*/
 
2569
            inc_right_mgap = TRUE;
 
2570
        else
 
2571
            inc_right_mgap = FALSE;
 
2572
        
 
2573
        for(numseg = 0; numseg<dsp->numseg; ++numseg) {
 
2574
            if(dsp->lens[k] >0) {
 
2575
                s1 = (Int4)k*(Int4)(dsp->dim)+(Int4)m_order;
 
2576
                master_pos = dsp->starts[s1];
 
2577
                collect = FALSE;
 
2578
                if(master_pos == -1) {  /*gap in the master sequence. It is an insertion*/
 
2579
                    strand = ma_strand;
 
2580
                    left_end_gap = is_end_gaps_for_master(dsp, m_order, k_seg, k, TRUE);
 
2581
                    right_end_gap = is_end_gaps_for_master(dsp, m_order, k_seg, k, FALSE);
 
2582
                    if(left_end_gap && inc_left_mgap && !map) {
 
2583
                        collect = TRUE;
 
2584
                        t_range.left = offset;
 
2585
                        t_range.right = offset + dsp->lens[k] -1;
 
2586
                        offset += dsp->lens[k];
 
2587
                    }
 
2588
                    if(right_end_gap && inc_right_mgap && !map) {
 
2589
                        collect = TRUE;
 
2590
                        t_range.left = t_range.right +1;
 
2591
                        t_range.right = t_range.left + dsp->lens[k] -1;
 
2592
                    }
 
2593
                    if(!left_end_gap && !right_end_gap) {
 
2594
                        use_stop = TRUE;
 
2595
                        if((strand != Seq_strand_minus && rev) || (strand == Seq_strand_minus && rev == FALSE))
 
2596
                            use_stop = FALSE;
 
2597
                        if(use_stop)
 
2598
                            update_seq_loc(c_stop, c_stop, 0, a_slp);
 
2599
                        else
 
2600
                            update_seq_loc(c_start, c_start, 0, a_slp);
 
2601
                        collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
 
2602
                        if(collect) {
 
2603
                            ++(t_range.left);
 
2604
                            if(!map) {
 
2605
                                t_range.right = t_range.left+dsp->lens[k]-1;
 
2606
                                offset += dsp->lens[k];
 
2607
                            }
 
2608
                        }
 
2609
                    }
 
2610
                    off_start = 0;
 
2611
                    off_stop = 0;
 
2612
                } else {/*master is not a gap*/
 
2613
                    c_start = dsp->starts[s1];
 
2614
                    c_stop = c_start + dsp->lens[k] -1;
 
2615
                    update_seq_loc(c_start, c_stop, 0, a_slp);
 
2616
                    collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
 
2617
                    if(collect) {
 
2618
                            off_start = MAX(0, (m_start - c_start));
 
2619
                            off_stop = MAX(0, (c_stop - m_stop));
 
2620
                    }
 
2621
                }
 
2622
                if(collect) {
 
2623
                    for(sip = dsp->ids, i=0; sip!=NULL; sip = sip->next, ++i) {
 
2624
                        load = TRUE;
 
2625
                        start = dsp->starts[k*(dsp->dim) +i];
 
2626
                        if(map) {
 
2627
                            /*multiple pairwise, ignore the master and the gap in the master*/
 
2628
                            if(i == m_order)
 
2629
                                load = FALSE;
 
2630
                            else if(master_pos == -1 && start == -1)
 
2631
                                load= FALSE;
 
2632
                        }
 
2633
                        if(load)
 
2634
                            {
 
2635
                                strand = align_strand_get(dsp->strands, i);
 
2636
                                if(start != -1) {
 
2637
                                    stop = start + dsp->lens[k] -1;
 
2638
                                    if(master_pos == -1 && map) { /*master sequence*/
 
2639
                                        
 
2640
                                        seg_type = INS_SEG;
 
2641
                                        t_range.right = dsp->lens[k];
 
2642
                                    } else {
 
2643
                                        if(check_reverse_strand(c_strand, strand)) {
 
2644
                                            start += off_stop;
 
2645
                                            stop -= off_start;
 
2646
                                        } else {
 
2647
                                            start += off_start;
 
2648
                                            stop -= off_stop;
 
2649
                                        }
 
2650
                                        seg_type = REG_SEG;
 
2651
                                    }
 
2652
                                } else {
 
2653
                                    seg_type = GAP_SEG;
 
2654
                                    start = -1;
 
2655
                                    stop = dsp->lens[k];
 
2656
                                } 
 
2657
                                load_align_data(&head, start, stop, strand, sip, rev, seg_type, t_range, ck_interval, i, 1);
 
2658
                            }
 
2659
                    }
 
2660
                }
 
2661
            }
 
2662
            if(rev)
 
2663
                --k;
 
2664
            else
 
2665
                ++k;
 
2666
        }
 
2667
        break;
 
2668
        
 
2669
    case 3:
 
2670
        ssp = (StdSegPtr)(align->segs);
 
2671
        if(cont) {
 
2672
            c_strand = get_master_strand_for_continous_ssp (ssp, m_sip);
 
2673
            rev = check_reverse_strand(m_strand, c_strand);
 
2674
            numseg = get_ssp_numseg (ssp);
 
2675
            if(rev)
 
2676
                k = numseg - 1;
 
2677
            else
 
2678
                k = 0;
 
2679
            for(t_numseg = 0; t_numseg <numseg; ++t_numseg) {
 
2680
                ssp = get_nth_ssp ((StdSegPtr)(align->segs), k);
 
2681
                is_found = FALSE;
 
2682
                for(loc= ssp->loc, i=0; loc!=NULL && !is_found; ++i, loc = loc->next) {
 
2683
                    if(SeqIdMatch(SeqLocId(loc), m_sip)) {
 
2684
                        master_loc = loc;
 
2685
                        m_order = i;
 
2686
                        if(loc->choice == SEQLOC_EMPTY)
 
2687
                            master_pos = -1;
 
2688
                        else {
 
2689
                            master_pos = SeqLocStart(loc);
 
2690
                            is_found = SeqLocOffset(m_slp, loc, &t_range, offset);
 
2691
                        }
 
2692
                        break;
 
2693
                    }
 
2694
                }
 
2695
                len = -1;
 
2696
                for(loc= ssp->loc, i = 0; loc!=NULL; ++i, loc = loc->next) {
 
2697
                    if(i != m_order) {
 
2698
                        if(loc->choice != SEQLOC_EMPTY)
 
2699
                            len = SeqLocLen(loc);
 
2700
                        break;
 
2701
                    }
 
2702
                }
 
2703
                                /*both segments are gaps */
 
2704
                if(is_found) {
 
2705
                    if(len == -1 && master_pos == -1)
 
2706
                        is_found = FALSE;
 
2707
                }
 
2708
                if(loc != NULL && (is_found || master_pos == -1)) {
 
2709
                    collect = FALSE;
 
2710
                    if(master_pos == -1) {/*the master is a gap, it is an insertion*/
 
2711
                        if(m_strand == Seq_strand_minus)
 
2712
                            update_seq_loc(c_start, c_start, 0, a_slp);
 
2713
                        else
 
2714
                            update_seq_loc(c_stop, c_stop, 0, a_slp);
 
2715
                        collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
 
2716
                        if(collect) {
 
2717
                            ++(t_range.left);
 
2718
                            if(!map) {
 
2719
                                if(!inverse) {
 
2720
                                    t_range.right = t_range.left+len * mag_val -1;
 
2721
                                    offset += len * mag_val;
 
2722
                                } else {
 
2723
                                    t_range.right = t_range.left+len / mag_val -1;
 
2724
                                    offset += len / mag_val;
 
2725
                                }
 
2726
                            }
 
2727
                        }
 
2728
                        off_start = 0;
 
2729
                        off_stop = 0;
 
2730
                    } else {
 
2731
                        c_start = SeqLocStart(master_loc);
 
2732
                        c_stop = SeqLocStop(master_loc);
 
2733
                        collect = TRUE;
 
2734
                        off_start = MAX(0, (m_start - c_start));
 
2735
                        off_stop = MAX(0, (c_stop - m_stop));
 
2736
                    }
 
2737
                    
 
2738
                    if(collect) {
 
2739
                        for(loc = ssp->loc, i= 0; loc != NULL; loc = loc->next, ++i) {
 
2740
                            load = TRUE;
 
2741
                            if(map && i == m_order)
 
2742
                                load = FALSE;
 
2743
                            if(load) {
 
2744
                                left = t_range.left;
 
2745
                                right = t_range.right;
 
2746
                                if(loc->choice == SEQLOC_EMPTY) {/*it is a gap */
 
2747
                                    strand = 0;
 
2748
                                    start = -1;
 
2749
                                    if(i == m_order)
 
2750
                                        stop = inverse ? (len /mag_val) : (len * mag_val);
 
2751
                                    else
 
2752
                                        stop = inverse ? SeqLocLen(master_loc) * mag_val : SeqLocLen(master_loc)/mag_val;
 
2753
                                    seg_type = GAP_SEG;
 
2754
                                } else {
 
2755
                                    start = SeqLocStart(loc);
 
2756
                                    stop = SeqLocStop(loc);
 
2757
                                    strand = SeqLocStrand(loc);
 
2758
                                    if(master_pos == -1 && map) {
 
2759
                                        seg_type = INS_SEG;
 
2760
                                        t_range.right = SeqLocLen(loc);
 
2761
                                    } else {
 
2762
                                        if(check_reverse_strand(strand, c_strand)) {
 
2763
                                            start += modify_offset(master_loc, loc, off_stop, &leftover);
 
2764
                                            t_range.left += leftover;
 
2765
                                            stop -= modify_offset(master_loc, loc, off_start, &leftover);
 
2766
                                            t_range.right += leftover;
 
2767
                                        } else {
 
2768
                                            start += modify_offset(master_loc, loc, off_start, &leftover);
 
2769
                                            t_range.left += leftover;
 
2770
                                            stop -= modify_offset(master_loc, loc, off_stop, &leftover);
 
2771
                                            t_range.right += leftover;
 
2772
                                        }
 
2773
                                        /* if(check_reverse_strand(c_strand, strand))
 
2774
                                           {
 
2775
                                           start += off_stop;
 
2776
                                           stop -= off_start;
 
2777
                                           }
 
2778
                                           else
 
2779
                                           {
 
2780
                                           start += off_start;
 
2781
                                           stop -= off_stop;
 
2782
                                           } */
 
2783
                                        seg_type = STD_SEG;
 
2784
                                    }
 
2785
                                }
 
2786
                                load_align_data(&head, start, stop, strand, SeqLocId(loc), rev, seg_type, t_range, ck_interval, i, 1);
 
2787
                                t_range.left = left;
 
2788
                                t_range.right = right;
 
2789
                                
 
2790
                            }
 
2791
                        }
 
2792
                    }
 
2793
                }
 
2794
                if(rev)
 
2795
                    --k;
 
2796
                else
 
2797
                    ++k;
 
2798
            }
 
2799
        } else {        /*end of if (count) */
 
2800
            chain = 0;
 
2801
            while(ssp) {
 
2802
                ++chain;
 
2803
                is_found = FALSE;
 
2804
                curr = NULL;
 
2805
                for(loc= ssp->loc, i=0; loc!=NULL && !is_found;) {
 
2806
                    if(SeqLocOffset(m_slp, loc, &t_range, offset)) {
 
2807
                        m_loc = loc;
 
2808
                        is_found = TRUE;
 
2809
                        break;
 
2810
                    } else {
 
2811
                        ++i;
 
2812
                        loc = loc->next;
 
2813
                    }
 
2814
                }
 
2815
                if(is_found) {
 
2816
                    m_order = i;
 
2817
                    off_start = MAX(0, (m_start - SeqLocStart(loc)));
 
2818
                    off_stop = MAX(0, (SeqLocStop(loc) - m_stop));
 
2819
                    c_strand = SeqLocStrand(loc);
 
2820
                    if(map)
 
2821
                        rev = check_reverse_strand(c_strand, m_strand);
 
2822
                    else
 
2823
                        rev = FALSE;
 
2824
                    for(loc = ssp->loc,i=0; loc != NULL; loc = loc->next,++i) {
 
2825
                        sip = SeqLocId(loc);
 
2826
                        if(!map|| (m_order !=i)) {
 
2827
                            start = SeqLocStart(loc);
 
2828
                            stop = SeqLocStop(loc);
 
2829
                            strand = SeqLocStrand(loc);
 
2830
                            left = t_range.left;
 
2831
                            right = t_range.right;
 
2832
                            if(check_reverse_strand(strand, c_strand)) {
 
2833
                                start += modify_offset(m_loc, loc, off_stop, &leftover);
 
2834
                                t_range.left += leftover;
 
2835
                                stop -= modify_offset(m_loc, loc, off_start, &leftover);
 
2836
                                t_range.right += leftover;
 
2837
                            } else {
 
2838
                                start += modify_offset(m_loc, loc, off_start, &leftover);
 
2839
                                t_range.left += leftover;
 
2840
                                stop -= modify_offset(m_loc, loc, off_stop, &leftover);
 
2841
                                t_range.right += leftover;
 
2842
                            }
 
2843
                            load_trunc_info(loc, &t_range);
 
2844
                            load_align_data(&curr, start, stop, strand, sip, rev, STD_SEG, t_range, ck_interval, i, chain);
 
2845
                            t_range.left = left;
 
2846
                            t_range.right = right;
 
2847
                        }
 
2848
                    }
 
2849
                }
 
2850
                LinkAlignData(&head, curr);
 
2851
                ssp = ssp->next;
 
2852
            }
 
2853
        }
 
2854
        break;
 
2855
        
 
2856
    case 1:
 
2857
        ddp = (DenseDiagPtr)(align->segs);
 
2858
        chain = 0;
 
2859
        while(ddp) {
 
2860
            ++chain;
 
2861
            curr = NULL;
 
2862
            m_order = get_master_order(ddp->id, m_sip);
 
2863
            if(m_order != -1) {
 
2864
                c_strand = align_strand_get(ddp->strands, m_order);
 
2865
                c_start = ddp->starts[m_order];
 
2866
                c_stop = c_start + ddp->len -1;
 
2867
                update_seq_loc(c_start, c_stop, 0, a_slp);
 
2868
                if(SeqLocOffset(m_slp, a_slp, &t_range, offset)) {
 
2869
                    rev = check_reverse_strand(m_strand, c_strand);
 
2870
                    off_start = MAX(0, (m_start-c_start));
 
2871
                    off_stop = MAX(0, (c_stop - m_stop));
 
2872
                    for(sip = ddp->id, i=0; sip!=NULL; sip = sip->next, ++i) {
 
2873
                        if(!map|| i != m_order) {
 
2874
                            start = ddp->starts[i];
 
2875
                            stop = start + ddp->len -1;
 
2876
                            strand = align_strand_get(ddp->strands, i);
 
2877
                            if(check_reverse_strand(strand, c_strand)) {
 
2878
                                start += off_stop;
 
2879
                                stop -= off_start;
 
2880
                            } else {
 
2881
                                start += off_start;
 
2882
                                stop -= off_stop;
 
2883
                            }
 
2884
                            load_align_data(&curr, start, stop, strand, sip, rev, DIAG_SEG, t_range, ck_interval, i, chain);
 
2885
                        }
 
2886
                    }
 
2887
                }
 
2888
            }
 
2889
            LinkAlignData(&head, curr);
 
2890
            ddp = ddp->next;
 
2891
        }
 
2892
        break;
 
2893
    default:
 
2894
        break;
 
2895
    }
 
2896
    
 
2897
    SeqLocFree(a_slp);
 
2898
    return head;
 
2899
}
 
2900
 
 
2901
                                        
 
2902
 
 
2903
static Boolean NEAR GatherSeqAlign(InternalGCCPtr gccp, SeqAlignPtr sap,
 
2904
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Boolean check, Uint1 obj_type)
 
2905
{
 
2906
        GatherContextPtr gcp;
 
2907
        GatherScopePtr gsp;
 
2908
        Int2 LocateItem = 0;
 
2909
        Pointer LocateData = NULL;
 
2910
        Uint1 thistype;
 
2911
        SeqLocPtr slp, target[2];
 
2912
        Boolean takeit=TRUE, checkseq = FALSE;
 
2913
        Int2 j, numcheck=0;
 
2914
        Int4 offset = 0;
 
2915
        Boolean check_interval;
 
2916
        AlignDataPtr adp;
 
2917
        SeqAlignPtr prevsap = NULL;
 
2918
 
 
2919
        if (sap == NULL) return TRUE;
 
2920
 
 
2921
        if(obj_type != OBJ_SEQALIGN && obj_type != OBJ_SEQHIST_ALIGN)
 
2922
                return TRUE;
 
2923
 
 
2924
        gcp = &(gccp->gc);
 
2925
        gsp = &(gccp->scope);
 
2926
 
 
2927
        if (gsp->ignore[obj_type])
 
2928
                return TRUE; 
 
2929
 
 
2930
        if (gccp->locatetype == obj_type)
 
2931
        {
 
2932
                LocateItem = gccp->locateID;
 
2933
                LocateData = gccp->locatePtr;
 
2934
        }
 
2935
 
 
2936
        thistype = obj_type;
 
2937
 
 
2938
 
 
2939
        if (gsp->target != NULL && check)
 
2940
        {
 
2941
                numcheck = 1;
 
2942
                target[0] = gsp->target;
 
2943
                if (gccp->segloc != NULL)
 
2944
                {
 
2945
                        numcheck = 2;
 
2946
                        target[1] = gccp->segloc;
 
2947
                }
 
2948
                offset = gsp->offset;
 
2949
                checkseq = TRUE;
 
2950
        }
 
2951
 
 
2952
        check_interval = (gsp->nointervals == FALSE);
 
2953
        while (sap != NULL)
 
2954
        {
 
2955
                gccp->itemIDs[obj_type]++;
 
2956
                if (LocateItem == gccp->itemIDs[obj_type])
 
2957
                        in_scope = TRUE;
 
2958
                if (LocateData == (Pointer)sap)
 
2959
                        in_scope = TRUE;
 
2960
 
 
2961
                if (in_scope)
 
2962
                {
 
2963
                        gcp->previtem = (Pointer)prevsap;
 
2964
                        gcp->prevtype = thistype;
 
2965
                        gcp->parentitem = tparent;
 
2966
                        gcp->parenttype = ttype;
 
2967
                        gcp->itemID = gccp->itemIDs[obj_type];
 
2968
                        gcp->prevlink = prevlink;
 
2969
                        gcp->thisitem = (Pointer)sap;
 
2970
                        gcp->thistype = thistype;
 
2971
                        GatherAddToStack(gcp);
 
2972
                        if (checkseq)
 
2973
                        {
 
2974
                                takeit = FALSE;
 
2975
                                for (j =0; ((j<numcheck) && (!takeit)); j++)
 
2976
                                {
 
2977
                                        slp = target[j];
 
2978
                                        FreeAlignData(gcp->adp);
 
2979
                                        gcp->adp = NULL;
 
2980
                                        adp = gather_align_data(slp, sap, offset, check_interval, gsp->mapinsert);
 
2981
                                        if(adp == NULL)
 
2982
                                                takeit = FALSE;
 
2983
                                        else
 
2984
                                        {
 
2985
                                                takeit = TRUE;
 
2986
                                                gcp->adp = adp;
 
2987
                                        }
 
2988
                                        
 
2989
                                }
 
2990
                                if(takeit)
 
2991
                                {
 
2992
                                        if (! (*(gccp->userfunc))(gcp))
 
2993
                                                return FALSE;
 
2994
                                }
 
2995
                        }
 
2996
                        else
 
2997
                        {
 
2998
                                if(takeit && check)
 
2999
                                        if (! (*(gccp->userfunc))(gcp))
 
3000
                                                return FALSE;
 
3001
                        }
 
3002
                        if (LocateItem) return FALSE;
 
3003
                        if (LocateData) return FALSE;
 
3004
                }
 
3005
 
 
3006
                if (sap->segtype == SAS_DISC)
 
3007
                {
 
3008
                        gcp->indent++;
 
3009
                        if (! GatherSeqAlign(gccp, (SeqAlignPtr)(sap->segs),
 
3010
                               thistype, (Pointer)sap, &(sap->segs),
 
3011
                               in_scope, check, OBJ_SEQALIGN))
 
3012
                        {
 
3013
                           return FALSE;
 
3014
                        }
 
3015
                        gcp->indent--;
 
3016
                }
 
3017
                             
 
3018
 
 
3019
                prevsap = sap;
 
3020
                prevlink = (Pointer PNTR)&(sap->next);
 
3021
                sap = sap->next;
 
3022
        }
 
3023
        return TRUE;
 
3024
}
 
3025
 
 
3026
static Boolean NEAR GatherSeqGraph(InternalGCCPtr gccp, SeqGraphPtr sgp,
 
3027
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
 
3028
{
 
3029
        GatherContextPtr gcp;
 
3030
        GatherScopePtr gsp;
 
3031
        Int2 LocateItem = 0;
 
3032
        Pointer LocateData = NULL;
 
3033
        Uint1 thistype;
 
3034
 
 
3035
        if (sgp == NULL) return TRUE;
 
3036
 
 
3037
        gcp = &(gccp->gc);
 
3038
        gsp = &(gccp->scope);
 
3039
 
 
3040
        if (gsp->ignore[OBJ_SEQGRAPH])
 
3041
                return TRUE;
 
3042
 
 
3043
        LocateItem = gccp->locateID;
 
3044
        LocateData = gccp->locatePtr;
 
3045
 
 
3046
        thistype = OBJ_SEQGRAPH;
 
3047
        gcp->previtem = NULL;
 
3048
        gcp->prevtype = thistype;
 
3049
        gcp->parentitem = tparent;
 
3050
        gcp->parenttype = ttype;
 
3051
 
 
3052
        while (sgp != NULL)
 
3053
        {
 
3054
                gccp->itemIDs[OBJ_SEQGRAPH]++;
 
3055
                if (LocateItem == gccp->itemIDs[OBJ_SEQGRAPH])
 
3056
                        in_scope = TRUE;
 
3057
                if (LocateData == (Pointer)sgp)
 
3058
                        in_scope = TRUE;
 
3059
 
 
3060
                if (in_scope)
 
3061
                {
 
3062
                        gcp->itemID = gccp->itemIDs[OBJ_SEQGRAPH];
 
3063
                        gcp->thisitem = (Pointer)sgp;
 
3064
                        gcp->thistype = thistype;
 
3065
                        GatherAddToStack(gcp);
 
3066
                        gcp->prevlink = prevlink;
 
3067
                        if (! (*(gccp->userfunc))(gcp))
 
3068
                                return FALSE;
 
3069
                        if (LocateItem) return FALSE;
 
3070
                        if (LocateData != NULL) return FALSE;
 
3071
                }
 
3072
 
 
3073
                gcp->previtem = (Pointer)sgp;
 
3074
                prevlink = (Pointer PNTR)&(sgp->next);
 
3075
                sgp = sgp->next;
 
3076
        }
 
3077
        return TRUE;
 
3078
}
 
3079
 
 
3080
static Boolean NEAR GatherSeqAnnot(InternalGCCPtr gccp, SeqAnnotPtr sap,
 
3081
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
 
3082
{
 
3083
        GatherContextPtr gcp;
 
3084
        GatherScopePtr gsp;
 
3085
        SeqAnnotPtr prevsap = NULL;
 
3086
        Int2 LocateItem = 0;
 
3087
        Pointer LocateData = NULL;
 
3088
        Uint1 thistype;
 
3089
 
 
3090
        if (sap == NULL) return TRUE;
 
3091
 
 
3092
        gcp = &(gccp->gc);
 
3093
        gsp = &(gccp->scope);
 
3094
 
 
3095
        if (gsp->ignore[OBJ_SEQANNOT])
 
3096
                return TRUE;
 
3097
 
 
3098
        if ((! gsp->currlevel) && (gsp->ignore_top))
 
3099
                return TRUE;
 
3100
 
 
3101
        if (gccp->locatetype == OBJ_SEQANNOT)
 
3102
        {
 
3103
                LocateItem = gccp->locateID;
 
3104
                LocateData = gccp->locatePtr;
 
3105
        }
 
3106
        else
 
3107
                LocateItem = 0;
 
3108
 
 
3109
        while (sap != NULL)
 
3110
        {
 
3111
                thistype = OBJ_SEQANNOT;
 
3112
                gccp->itemIDs[OBJ_SEQANNOT]++;
 
3113
                if (LocateItem == gccp->itemIDs[OBJ_SEQANNOT])
 
3114
                        in_scope = TRUE;
 
3115
                if (LocateData == (Pointer)sap)
 
3116
                        in_scope = TRUE;
 
3117
 
 
3118
                gcp->thisitem = (Pointer)sap;
 
3119
                gcp->thistype = thistype;
 
3120
                gcp->itemID = gccp->itemIDs[OBJ_SEQANNOT];
 
3121
                GatherAddToStack(gcp);
 
3122
 
 
3123
                if (in_scope)
 
3124
                {
 
3125
                        gcp->previtem = (Pointer) prevsap;
 
3126
                        gcp->prevtype = thistype;
 
3127
                        gcp->parentitem = tparent;
 
3128
                        gcp->parenttype = ttype;
 
3129
                        gcp->prevlink = prevlink;
 
3130
                        if (! (*(gccp->userfunc))(gcp))
 
3131
                                return FALSE;
 
3132
                        if (LocateItem) return FALSE;
 
3133
                        if (LocateData != NULL) return FALSE;
 
3134
                }
 
3135
 
 
3136
                gcp->indent++;
 
3137
                switch (sap->type)
 
3138
                {
 
3139
                
 
3140
                        case 1:     /* feature table */
 
3141
                                if (gccp->useSeqMgrIndexes) {
 
3142
                                        /* now sending targeted features all at once regardless of packaging - so do nothing here */
 
3143
                                } else {
 
3144
                                        if (! GatherSeqFeat(gccp, (SeqFeatPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope, OBJ_SEQFEAT))
 
3145
                                                return FALSE;
 
3146
                                }
 
3147
                                break;
 
3148
                        case 2:     /* alignments */
 
3149
                                if (! GatherSeqAlign(gccp, (SeqAlignPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope, TRUE, OBJ_SEQALIGN))
 
3150
                                        return FALSE;
 
3151
                                break;
 
3152
                        case 3:     /* graphs */
 
3153
                                if (! GatherSeqGraph(gccp, (SeqGraphPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope))
 
3154
                                        return FALSE;
 
3155
                                break;
 
3156
 
 
3157
                }
 
3158
                gcp->indent--;
 
3159
 
 
3160
                prevsap = sap;
 
3161
                prevlink = (Pointer PNTR)&(sap->next);
 
3162
                sap = sap->next;
 
3163
        }
 
3164
        return TRUE;
 
3165
}
 
3166
 
 
3167
 
 
3168
 
 
3169
static Boolean NEAR GatherSeqHist(InternalGCCPtr gccp, SeqHistPtr hist,
 
3170
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Boolean check_seq)
 
3171
{
 
3172
        GatherContextPtr gcp;
 
3173
        GatherScopePtr gsp;
 
3174
        Int2 LocateItem = 0;
 
3175
        Pointer LocateData = NULL;
 
3176
        Uint1 thistype;
 
3177
 
 
3178
        if(hist == NULL) return TRUE;
 
3179
 
 
3180
        gcp = &(gccp->gc);
 
3181
        gsp = &(gccp->scope);
 
3182
 
 
3183
        if(gsp->ignore[OBJ_SEQHIST])
 
3184
                return TRUE;
 
3185
 
 
3186
        if (gccp->locatetype == OBJ_SEQHIST)
 
3187
        {
 
3188
                LocateItem = gccp->locateID;
 
3189
                LocateData = gccp->locatePtr;
 
3190
        }
 
3191
        else
 
3192
                LocateItem = 0;
 
3193
 
 
3194
        gccp->itemIDs[OBJ_SEQHIST]++;
 
3195
        thistype = OBJ_SEQHIST;
 
3196
        if (LocateItem == gccp->itemIDs[OBJ_SEQHIST])
 
3197
                in_scope = TRUE;
 
3198
        if (LocateData == (Pointer)(hist))
 
3199
                in_scope = TRUE;
 
3200
 
 
3201
        gcp->thistype = thistype;
 
3202
        gcp->thisitem = (Pointer)(hist);
 
3203
        gcp->itemID = gccp->itemIDs[OBJ_SEQHIST];
 
3204
        GatherAddToStack(gcp);
 
3205
 
 
3206
        if (in_scope)
 
3207
        {
 
3208
                gcp->previtem = NULL;
 
3209
                gcp->prevtype = 0;
 
3210
                gcp->parentitem = (Pointer)tparent;
 
3211
                gcp->parenttype = ttype;
 
3212
                gcp->prevlink = prevlink;
 
3213
 
 
3214
                if (! (*(gccp->userfunc))(gcp))
 
3215
                        return FALSE;
 
3216
                if (LocateItem) return FALSE;
 
3217
                if (LocateData != NULL) return FALSE;
 
3218
        }
 
3219
        if((hist->assembly!=NULL) && (!gsp->ignore[OBJ_SEQHIST_ALIGN]))
 
3220
                GatherSeqAlign(gccp,(SeqAlignPtr)(hist->assembly), thistype, 
 
3221
                  (Pointer)(hist),(Pointer PNTR)&(hist->assembly),
 
3222
                  in_scope, check_seq, OBJ_SEQHIST_ALIGN);
 
3223
        return TRUE;
 
3224
 
 
3225
}
 
3226
 
 
3227
 
 
3228
 
 
3229
 
 
3230
 
 
3231
static Boolean NEAR GatherBioseqFunc (InternalGCCPtr gccp, BioseqPtr bsp,
 
3232
         Pointer parent, Uint2 parenttype, SeqEntryPtr prev,
 
3233
             Pointer PNTR prevlink, SeqEntryPtr curr, Boolean in_scope)
 
3234
{
 
3235
        GatherContextPtr gcp;
 
3236
        GatherScopePtr gsp;
 
3237
        Boolean takeit, in_range=TRUE, rev, free_seg, trunc_l, trunc_r;
 
3238
        Int2 LocateItem = 0, segctr, first_seg, last_seg;
 
3239
        Pointer LocateData = NULL;
 
3240
        ValNode vn;
 
3241
        SeqLocPtr head, slp, target=NULL, tslp, segloc;
 
3242
        SeqLocPtr targets[2];
 
3243
        Int4 offset, toffset, seglen, tlen;
 
3244
        GatherRangePtr rdp;
 
3245
        Uint1 thistype, segtype;
 
3246
        Int2 j, numcheck;
 
3247
        Boolean match_target = TRUE, do_seg, is_delta;
 
3248
        DeltaSeqPtr dsp;
 
3249
        Pointer dataptr;  /* used for OBJ_BIOSEQ_SEG and OBJ_BIOSEQ_DELTA */
 
3250
 
 
3251
        if (bsp == NULL)
 
3252
                return TRUE;
 
3253
 
 
3254
        gcp = &(gccp->gc);
 
3255
        gsp = &(gccp->scope);
 
3256
 
 
3257
        takeit = in_scope;
 
3258
        head = NULL;      
 
3259
        if (gsp->ignore[OBJ_BIOSEQ])
 
3260
                takeit = FALSE;
 
3261
        else if ((takeit) && (gsp->target != NULL))
 
3262
        {
 
3263
                if (bsp != gccp->bsp)
 
3264
                        takeit = FALSE;
 
3265
        }
 
3266
 
 
3267
        gccp->itemIDs[OBJ_BIOSEQ]++;
 
3268
        gcp->itemID = gccp->itemIDs[OBJ_BIOSEQ];
 
3269
        if (gccp->locatetype == OBJ_BIOSEQ)
 
3270
        {
 
3271
                LocateItem = gccp->locateID;
 
3272
                LocateData = gccp->locatePtr;
 
3273
                if (LocateItem == gccp->itemIDs[OBJ_BIOSEQ])
 
3274
                        takeit = TRUE;
 
3275
                if (LocateData == (Pointer)bsp)
 
3276
                        takeit = TRUE;
 
3277
        }
 
3278
 
 
3279
        thistype = OBJ_BIOSEQ;
 
3280
        gcp->thistype = thistype;
 
3281
        gcp->thisitem = (Pointer)bsp;
 
3282
        GatherAddToStack(gcp);
 
3283
 
 
3284
        if (gsp->target != NULL)
 
3285
        {
 
3286
                match_target = FALSE;
 
3287
                vn.choice = SEQLOC_WHOLE;
 
3288
                vn.data.ptrvalue = SeqIdFindBest (bsp->id, 0);
 
3289
                numcheck = 1;
 
3290
                targets[0] = gsp->target;
 
3291
                if (gccp->segloc != NULL)
 
3292
                {
 
3293
                        numcheck = 2;
 
3294
                        targets[1] = gccp->segloc;
 
3295
                }
 
3296
                for (j =0; !match_target && j<numcheck; j++)
 
3297
                {
 
3298
                        if(SeqLocOffset(targets[j], &vn, &(gcp->extremes), gsp->offset))
 
3299
                                match_target = TRUE;
 
3300
                }
 
3301
        }
 
3302
 
 
3303
        if (takeit)
 
3304
        {
 
3305
                gcp->sep = curr;
 
3306
                gcp->previtem = prev;
 
3307
                gcp->prevtype = OBJ_SEQENTRY;
 
3308
                gcp->parentitem = parent;
 
3309
                gcp->parenttype = parenttype;
 
3310
                gcp->thistype = thistype;
 
3311
                gcp->thisitem = (Pointer)bsp;
 
3312
                gcp->prevlink = prevlink;
 
3313
 
 
3314
                /*if (gsp->target != NULL)
 
3315
                {
 
3316
                        takeit = FALSE;
 
3317
                        vn.choice = SEQLOC_WHOLE;
 
3318
                        vn.data.ptrvalue = bsp->id;
 
3319
                        numcheck = 1;
 
3320
                        targets[0] = gsp->target;
 
3321
                        if (gccp->segloc != NULL)
 
3322
                        {
 
3323
                                numcheck = 2;
 
3324
                                targets[1] = gccp->segloc;
 
3325
                        }
 
3326
                        for (j =0; !takeit && j<numcheck; j++)
 
3327
                        {
 
3328
                                if(SeqLocOffset(targets[j], &vn, &(gcp->extremes), gsp->offset))
 
3329
                                        takeit = TRUE;
 
3330
                        }
 
3331
                }*/
 
3332
                takeit = match_target;
 
3333
 
 
3334
                if(!takeit)
 
3335
                        return FALSE;
 
3336
                if (! (*(gccp->userfunc))(gcp))
 
3337
                        return FALSE;
 
3338
                if (LocateItem) return FALSE;
 
3339
                if (LocateData != NULL) return FALSE;
 
3340
        }
 
3341
 
 
3342
 
 
3343
        gcp->indent++;
 
3344
 
 
3345
        if ((bsp->repr == Seq_repr_map) && (! gsp->ignore[OBJ_BIOSEQ_MAPFEAT]))
 
3346
        {
 
3347
                if (! GatherSeqFeat(gccp, (SeqFeatPtr)(bsp->seq_ext), thistype, (Pointer)bsp, &(bsp->seq_ext), in_scope, OBJ_BIOSEQ_MAPFEAT))
 
3348
                        return FALSE;
 
3349
        }
 
3350
 
 
3351
    do_seg = FALSE;   /* assume no pointer processing */
 
3352
 
 
3353
        if (! gsp->ignore[OBJ_BIOSEQ_SEG])
 
3354
        {
 
3355
                if ((bsp->repr == Seq_repr_seg) ||
 
3356
                        (bsp->repr == Seq_repr_ref))
 
3357
                {
 
3358
                        do_seg = TRUE;
 
3359
                        is_delta = FALSE;
 
3360
                        segtype = OBJ_BIOSEQ_SEG;
 
3361
                }
 
3362
        }
 
3363
 
 
3364
        if (! gsp->ignore[OBJ_BIOSEQ_DELTA])
 
3365
        {
 
3366
                if (bsp->repr == Seq_repr_delta)
 
3367
                {
 
3368
                        do_seg = TRUE;
 
3369
                        is_delta = TRUE;
 
3370
                        segtype = OBJ_BIOSEQ_DELTA;
 
3371
                }
 
3372
        }
 
3373
 
 
3374
        if (do_seg)   /* process segment, ref, delta sequence .ext */
 
3375
        {
 
3376
                if (bsp->repr == Seq_repr_seg)
 
3377
                {
 
3378
                        vn.next = NULL;
 
3379
                        vn.choice = SEQLOC_MIX;
 
3380
                        vn.data.ptrvalue = bsp->seq_ext;
 
3381
                        head = &vn;
 
3382
                }
 
3383
                else if (bsp->repr == Seq_repr_ref)
 
3384
                        head = (SeqLocPtr)(bsp->seq_ext);
 
3385
                else
 
3386
                {
 
3387
                        dsp = (DeltaSeqPtr)(bsp->seq_ext);  /* real data is here */
 
3388
                        head = DeltaSeqsToSeqLocs(dsp);  /* this for mapping only */
 
3389
                }
 
3390
 
 
3391
                if (head != NULL)
 
3392
                {
 
3393
                        segloc = NULL;
 
3394
                        segctr = 0;
 
3395
                        rev = gccp->rev;
 
3396
                        free_seg = FALSE;
 
3397
                        rdp = &(gcp->extremes);
 
3398
 
 
3399
                        if (gsp->target != NULL)   /* may have to map */
 
3400
                        {
 
3401
                                if (gccp->segloc != NULL)
 
3402
                                {
 
3403
                                        segloc = gccp->segloc;
 
3404
                                        first_seg = gccp->first_seg;
 
3405
                                        last_seg = gccp->last_seg;
 
3406
                                }
 
3407
                                else
 
3408
                                {
 
3409
                                        segloc = SeqLocCopyPart(head, SeqLocStart(gsp->target),
 
3410
                                        SeqLocStop(gsp->target), SeqLocStrand(gsp->target),
 
3411
                                        TRUE, &(first_seg), &(last_seg));
 
3412
                                    free_seg = TRUE;
 
3413
                                }
 
3414
 
 
3415
                                toffset = SeqLocStart(gsp->target); /* partial first seg */
 
3416
                                if (toffset)
 
3417
                                        trunc_l = TRUE;
 
3418
                                else
 
3419
                                        trunc_l = FALSE;
 
3420
                                if ((toffset + SeqLocLen(gsp->target)) < BioseqGetLen(bsp))
 
3421
                                        trunc_r = TRUE;
 
3422
                                else
 
3423
                                        trunc_r = FALSE;
 
3424
 
 
3425
                                tlen = SeqLocLen(segloc);
 
3426
 
 
3427
                                if (rev)
 
3428
                                {
 
3429
                                        segctr = first_seg;
 
3430
                                        last_seg = first_seg;
 
3431
                                        first_seg = segctr;
 
3432
                                        segctr = 0;
 
3433
                                }
 
3434
 
 
3435
                        }
 
3436
 
 
3437
                        if (gccp->locatetype == segtype)
 
3438
                        {
 
3439
                                LocateItem = gccp->locateID;
 
3440
                                LocateData = gccp->locatePtr;
 
3441
                        }
 
3442
 
 
3443
                        gcp->previtem = NULL;
 
3444
                        gcp->prevtype = 0;
 
3445
                        gcp->parentitem = (Pointer)bsp;
 
3446
                        gcp->parenttype = thistype;
 
3447
                        gcp->thistype = segtype;
 
3448
                        gcp->prevlink = (Pointer PNTR)&(bsp->seq_ext);
 
3449
                        offset = gsp->offset;
 
3450
 
 
3451
                        slp = NULL;
 
3452
                        tslp = NULL;
 
3453
                        rdp->l_trunc = FALSE;
 
3454
                        rdp->r_trunc = FALSE;
 
3455
                        while ((slp = SeqLocFindNext(head, slp)) != NULL)
 
3456
                        {
 
3457
                                if ((is_delta) && (segctr))  /* not first one */
 
3458
                                {
 
3459
                                        dsp = dsp->next;         /* move up dsp */
 
3460
                                        if (dsp == NULL)
 
3461
                                                ErrPostEx(SEV_FATAL,0,0,"GatherDeltaSeq: dsp is NULL");
 
3462
                                }
 
3463
 
 
3464
                                seglen = SeqLocLen (slp);
 
3465
                                segctr++;
 
3466
                                if (is_delta)
 
3467
                                        dataptr = (Pointer)dsp;
 
3468
                                else
 
3469
                                        dataptr = (Pointer)slp;
 
3470
 
 
3471
                                gccp->itemIDs[segtype]++;
 
3472
                                if (gccp->locatetype == segtype)
 
3473
                                {
 
3474
                                        if (LocateItem == gccp->itemIDs[segtype])
 
3475
                                                takeit = TRUE;
 
3476
                                        if (LocateData == dataptr)
 
3477
                                                takeit = TRUE;
 
3478
                                }
 
3479
 
 
3480
                                if (takeit)
 
3481
                                {
 
3482
                                        if (segloc != NULL)        /* adjust to target? */
 
3483
                                        {
 
3484
                                                if ((first_seg > segctr) || (last_seg < segctr))
 
3485
                                                        in_range = FALSE;
 
3486
                                                else
 
3487
                                                {
 
3488
                                                        in_range = TRUE;
 
3489
                                                        tslp = SeqLocFindNext(segloc, tslp);
 
3490
 
 
3491
                                                        rdp->l_trunc = FALSE;
 
3492
                                                        rdp->r_trunc = FALSE;
 
3493
 
 
3494
                                                        if (segctr == first_seg)
 
3495
                                                        {
 
3496
                                                                offset = gsp->offset; /* allow for partial */
 
3497
                                                                if (rev)
 
3498
                                                                {
 
3499
                                                                   if (trunc_r)
 
3500
                                                                        rdp->l_trunc = TRUE;
 
3501
                                                                }
 
3502
                                                                else
 
3503
                                                                {
 
3504
                                                                        if (trunc_l)
 
3505
                                                                                rdp->l_trunc = TRUE;
 
3506
                                                                }
 
3507
                                                        }
 
3508
                                                        else if (segctr == last_seg)
 
3509
                                                        {
 
3510
                                                                if (rev)
 
3511
                                                                {
 
3512
                                                                   if (trunc_l)
 
3513
                                                                        rdp->r_trunc = TRUE;
 
3514
                                                                }
 
3515
                                                                else
 
3516
                                                                {
 
3517
                                                                        if (trunc_r)
 
3518
                                                                                rdp->r_trunc = TRUE;
 
3519
                                                                }
 
3520
                                                        }
 
3521
 
 
3522
                                                        seglen = SeqLocLen(tslp);
 
3523
 
 
3524
                                                        if (rev)
 
3525
                                                        {
 
3526
                                                                rdp->right = offset + tlen - 1;
 
3527
                                                                rdp->left = rdp->right - seglen + 1;
 
3528
                                                        }
 
3529
                                                        else
 
3530
                                                        {
 
3531
                                                                rdp->left = offset;
 
3532
                                                                rdp->right = offset + seglen - 1;
 
3533
                                                        }
 
3534
                                                        rdp->strand = SeqLocStrand(tslp);
 
3535
                                                        tlen -= seglen;
 
3536
                                                }
 
3537
                                        }
 
3538
                                        else
 
3539
                                        {
 
3540
                                                rdp->left = offset;
 
3541
                                                rdp->right = offset + seglen - 1;
 
3542
                                                rdp->strand = SeqLocStrand(slp);
 
3543
                                        }
 
3544
 
 
3545
                                        if (in_range)  /* always in_range if no target */
 
3546
                                        {
 
3547
                                                gcp->thisitem = dataptr;
 
3548
                                                gcp->itemID = gccp->itemIDs[segtype];
 
3549
                                                GatherAddToStack(gcp);
 
3550
 
 
3551
                
 
3552
                                                if ((! (*(gccp->userfunc))(gcp)) || (LocateItem) ||
 
3553
                                                        (LocateData != NULL))
 
3554
                                                {
 
3555
                                                        if (free_seg)
 
3556
                                                                SeqLocFree(segloc);
 
3557
                                                        if (is_delta)
 
3558
                                                                SeqLocFree(head);
 
3559
                                                        return FALSE;
 
3560
                                                }
 
3561
                                        }
 
3562
                                }
 
3563
                                gcp->prevlink = (Pointer PNTR)&(((ValNodePtr)(dataptr))->next);
 
3564
                                gcp->previtem = dataptr;
 
3565
                                gcp->prevtype = segtype;
 
3566
                                offset += seglen;
 
3567
                        }
 
3568
 
 
3569
                        if (free_seg)
 
3570
                                SeqLocFree(segloc);
 
3571
                        if (is_delta)
 
3572
                                SeqLocFree(head);
 
3573
                }
 
3574
        }
 
3575
 
 
3576
        if(!GatherSeqHist(gccp, bsp->hist, thistype, (Pointer)bsp, (Pointer PNTR)&(bsp->hist), in_scope, match_target))
 
3577
                        return FALSE;
 
3578
 
 
3579
        if (! GatherSeqDescr(gccp, bsp->descr, thistype, (Pointer)bsp,
 
3580
                                   (Pointer PNTR)&(bsp->descr), in_scope))
 
3581
                return FALSE;
 
3582
 
 
3583
        if (! GatherSeqAnnot(gccp, bsp->annot, thistype, (Pointer)bsp,
 
3584
                                   (Pointer PNTR)&(bsp->annot), in_scope))
 
3585
                return FALSE;
 
3586
 
 
3587
        /* now send targeted features all at once regardless of packaging */
 
3588
        if (gccp->useSeqMgrIndexes && bsp == gccp->bsp) {
 
3589
                if (! ExploreSeqFeat (gccp, bsp, in_scope)) {
 
3590
                        return FALSE;
 
3591
                }
 
3592
        }
 
3593
 
 
3594
        gcp->indent--;
 
3595
 
 
3596
        return TRUE;
 
3597
}
 
3598
 
 
3599
static Boolean NEAR GatherBioseqSetFunc (InternalGCCPtr gccp, BioseqSetPtr bsp,
 
3600
           Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope,
 
3601
                   Pointer PNTR prevlink, SeqEntryPtr curr)
 
3602
{
 
3603
        GatherContextPtr gcp;
 
3604
        GatherScopePtr gsp;
 
3605
        Boolean takeit=TRUE, tscope, checkscope;
 
3606
        SeqEntryPtr sep, prevsep = NULL, scope = NULL;
 
3607
        Int2 LocateItem = 0;
 
3608
        Pointer LocateData = NULL;
 
3609
        Uint1 thistype;
 
3610
 
 
3611
        if (bsp == NULL)
 
3612
                return TRUE;
 
3613
 
 
3614
        gcp = &(gccp->gc);
 
3615
        gsp = &(gccp->scope);
 
3616
 
 
3617
        if (gsp->ignore[OBJ_BIOSEQSET])
 
3618
                takeit = FALSE;
 
3619
        else if (! in_scope)
 
3620
                takeit = FALSE;
 
3621
 
 
3622
        scope = gsp->scope;
 
3623
        if ((scope != NULL) && (! in_scope))
 
3624
                checkscope = TRUE;
 
3625
        else
 
3626
                checkscope = FALSE;
 
3627
                
 
3628
        gccp->itemIDs[OBJ_BIOSEQSET]++;
 
3629
        gcp->itemID = gccp->itemIDs[OBJ_BIOSEQSET];
 
3630
 
 
3631
        if (gccp->locatetype == OBJ_BIOSEQSET)
 
3632
        {
 
3633
                if ((gccp->locateID == gccp->itemIDs[OBJ_BIOSEQSET]) ||
 
3634
                        ((Pointer)bsp == gccp->locatePtr))
 
3635
                {
 
3636
                        takeit = TRUE;
 
3637
                        LocateItem = gccp->locateID;
 
3638
                        LocateData = gccp->locatePtr;
 
3639
                }
 
3640
        }
 
3641
 
 
3642
        thistype = OBJ_BIOSEQSET;
 
3643
        gcp->thistype = thistype;
 
3644
        gcp->thisitem = (Pointer)bsp;
 
3645
        GatherAddToStack(gcp);
 
3646
 
 
3647
        if (takeit)
 
3648
        {
 
3649
                gcp->sep = curr;
 
3650
                gcp->previtem = prev;
 
3651
                gcp->prevtype = OBJ_SEQENTRY;
 
3652
                gcp->parentitem = parent;
 
3653
                gcp->parenttype = parenttype;
 
3654
                gcp->prevlink = prevlink;
 
3655
 
 
3656
 
 
3657
                if (! (*(gccp->userfunc))(gcp))
 
3658
                        return FALSE;
 
3659
                if (LocateItem) return FALSE;
 
3660
                if (LocateData != NULL) return FALSE;
 
3661
        }
 
3662
        gcp->indent++;
 
3663
        if (! GatherSeqDescr(gccp, bsp->descr, thistype, (Pointer)bsp,
 
3664
                               (Pointer PNTR)&(bsp->descr), in_scope))
 
3665
                return FALSE;
 
3666
 
 
3667
        if (! GatherSeqAnnot(gccp, bsp->annot, thistype, (Pointer)bsp,
 
3668
                       (Pointer PNTR)&(bsp->annot), in_scope))
 
3669
                return FALSE;
 
3670
 
 
3671
        tscope = in_scope;
 
3672
        prevlink = (Pointer PNTR)&(bsp->seq_set);
 
3673
        for (sep = bsp->seq_set; sep != NULL; sep = sep->next)
 
3674
        {
 
3675
                gcp->previtem = prevsep;
 
3676
                gcp->prevtype = OBJ_SEQENTRY;
 
3677
                gcp->parentitem = (Pointer)bsp;
 
3678
                gcp->parenttype = thistype;
 
3679
                gcp->prevlink = prevlink;
 
3680
 
 
3681
                if (checkscope)
 
3682
                {
 
3683
                        if (sep == scope)
 
3684
                                tscope = TRUE;
 
3685
                        else
 
3686
                                tscope = FALSE;
 
3687
                }
 
3688
 
 
3689
                if (! GatherSeqEntryFunc(sep, gccp, (Pointer)bsp, OBJ_BIOSEQSET, prevsep, tscope, prevlink))
 
3690
                        return FALSE;
 
3691
 
 
3692
                if (checkscope)
 
3693
                {
 
3694
                        if (tscope == TRUE)  /* just found it */
 
3695
                        {
 
3696
                                checkscope = FALSE;   /* don't look anymore */
 
3697
                                tscope = FALSE;       /* the siblings not in scope */
 
3698
                                gsp->scope = NULL;    /* no more to look */
 
3699
                        }
 
3700
                        else if (gsp->scope == NULL)   /* found lower down */
 
3701
                        {
 
3702
                                checkscope = FALSE;
 
3703
                                tscope = FALSE;
 
3704
                        }
 
3705
                }
 
3706
 
 
3707
                prevsep = sep;
 
3708
                prevlink = (Pointer PNTR)&(sep->next);
 
3709
        }
 
3710
 
 
3711
        gcp->indent--;  /* reset to original indent level */
 
3712
        return TRUE;
 
3713
}
 
3714
 
 
3715
static Boolean NEAR GatherSeqEntryFunc (SeqEntryPtr sep, InternalGCCPtr igccp,
 
3716
           Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope,
 
3717
                   Pointer PNTR prevlink)
 
3718
{
 
3719
        if (sep == NULL)
 
3720
                return TRUE;
 
3721
 
 
3722
        if (IS_Bioseq(sep))
 
3723
        {
 
3724
                if (! GatherBioseqFunc(igccp, (BioseqPtr)(sep->data.ptrvalue), parent, parenttype, prev, prevlink, sep, in_scope))
 
3725
                        return FALSE;
 
3726
        }
 
3727
        else
 
3728
        {
 
3729
                if (! GatherBioseqSetFunc(igccp, (BioseqSetPtr)(sep->data.ptrvalue), parent, parenttype, prev, in_scope, prevlink, sep))
 
3730
                        return FALSE;
 
3731
        }
 
3732
 
 
3733
        return TRUE;
 
3734
}
 
3735
 
 
3736
static Boolean NEAR GatherSeqSubCit(InternalGCCPtr gccp, CitSubPtr csp,
 
3737
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
 
3738
{
 
3739
        GatherContextPtr gcp;
 
3740
        GatherScopePtr gsp;
 
3741
        Boolean doit = TRUE;
 
3742
        Int2 LocateItem = 0;
 
3743
        Pointer LocateData = NULL;
 
3744
 
 
3745
        if (csp == NULL) return TRUE;
 
3746
 
 
3747
        gcp = &(gccp->gc);
 
3748
        gsp = &(gccp->scope);
 
3749
 
 
3750
        if (gsp->ignore[OBJ_SEQSUB_CIT])
 
3751
                return TRUE;
 
3752
 
 
3753
        gccp->itemIDs[OBJ_SEQSUB_CIT]++;
 
3754
 
 
3755
        if (gccp->locatetype == OBJ_SEQSUB_CIT)
 
3756
        {
 
3757
                LocateItem = gccp->locateID;
 
3758
                LocateData = gccp->locatePtr;
 
3759
                if ((gccp->itemIDs[OBJ_SEQSUB_CIT] != LocateItem) &&
 
3760
                        (LocateData != (Pointer)csp))
 
3761
                        doit = FALSE;
 
3762
        }
 
3763
 
 
3764
        gcp->previtem = NULL;
 
3765
        gcp->prevtype = 0;
 
3766
        gcp->parentitem = tparent;
 
3767
        gcp->parenttype = ttype;
 
3768
        gcp->thisitem = (Pointer)csp;
 
3769
        gcp->thistype = OBJ_SEQSUB_CIT;
 
3770
        gcp->prevlink = prevlink;
 
3771
        gcp->itemID = gccp->itemIDs[OBJ_SEQSUB_CIT];
 
3772
        GatherAddToStack(gcp);
 
3773
 
 
3774
 
 
3775
        if (doit)
 
3776
        {
 
3777
                if (! (*(gccp->userfunc))(gcp))
 
3778
                        return FALSE;
 
3779
                if (LocateItem) return FALSE;
 
3780
                if (LocateData) return FALSE;
 
3781
        }
 
3782
 
 
3783
        return TRUE;
 
3784
}
 
3785
 
 
3786
static Boolean NEAR GatherSeqSubContact(InternalGCCPtr gccp, ContactInfoPtr cip,
 
3787
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
 
3788
{
 
3789
        GatherContextPtr gcp;
 
3790
        GatherScopePtr gsp;
 
3791
        Int2 LocateItem = 0;
 
3792
        Pointer LocateData = NULL;
 
3793
        Boolean doit = TRUE;
 
3794
 
 
3795
        if (cip == NULL) return TRUE;
 
3796
 
 
3797
        gcp = &(gccp->gc);
 
3798
        gsp = &(gccp->scope);
 
3799
 
 
3800
        if (gsp->ignore[OBJ_SEQSUB_CONTACT])
 
3801
                return TRUE;
 
3802
 
 
3803
        gccp->itemIDs[OBJ_SEQSUB_CONTACT]++;
 
3804
 
 
3805
        if (gccp->locatetype == OBJ_SEQSUB_CONTACT)
 
3806
        {
 
3807
                LocateItem = gccp->locateID;
 
3808
                LocateData = gccp->locatePtr;
 
3809
                if ((gccp->itemIDs[OBJ_SEQSUB_CONTACT] != LocateItem) &&
 
3810
                        ((Pointer)cip != LocateData))
 
3811
                        doit = FALSE;
 
3812
        }
 
3813
 
 
3814
        gcp->previtem = NULL;
 
3815
        gcp->prevtype = 0;
 
3816
        gcp->parentitem = tparent;
 
3817
        gcp->parenttype = ttype;
 
3818
        gcp->thisitem = (Pointer)cip;
 
3819
        gcp->thistype = OBJ_SEQSUB_CONTACT;
 
3820
        gcp->prevlink = prevlink;
 
3821
        gcp->itemID = gccp->itemIDs[OBJ_SEQSUB_CONTACT];
 
3822
        GatherAddToStack(gcp);
 
3823
 
 
3824
        if (doit)
 
3825
        {
 
3826
                if (! (*(gccp->userfunc))(gcp))
 
3827
                        return FALSE;
 
3828
                if (LocateItem) return FALSE;
 
3829
                if (LocateData != NULL) return FALSE;
 
3830
        }
 
3831
 
 
3832
        return TRUE;
 
3833
}
 
3834
 
 
3835
static Boolean NEAR GatherSubBlock(InternalGCCPtr gccp, SubmitBlockPtr sbp,
 
3836
        Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
 
3837
{
 
3838
        GatherContextPtr gcp;
 
3839
        GatherScopePtr gsp;
 
3840
        Int2 LocateItem = 0;
 
3841
        Pointer LocateData = NULL;
 
3842
        Boolean doit = TRUE;
 
3843
 
 
3844
        if (sbp == NULL) return TRUE;
 
3845
 
 
3846
        gcp = &(gccp->gc);
 
3847
        gsp = &(gccp->scope);
 
3848
 
 
3849
        if (gsp->ignore[OBJ_SUBMIT_BLOCK])
 
3850
                return TRUE;
 
3851
 
 
3852
        gccp->itemIDs[OBJ_SUBMIT_BLOCK]++;
 
3853
 
 
3854
        if (gccp->locatetype != 0) {
 
3855
                doit = FALSE;
 
3856
                if (gccp->locatetype == OBJ_SUBMIT_BLOCK)
 
3857
                {
 
3858
                        LocateItem = gccp->locateID;
 
3859
                        LocateData = gccp->locatePtr;
 
3860
                        if (gccp->itemIDs[OBJ_SUBMIT_BLOCK] == LocateItem)
 
3861
                                doit = TRUE;
 
3862
                        if (LocateData == (Pointer)sbp)
 
3863
                                doit = TRUE;
 
3864
                }
 
3865
        }
 
3866
 
 
3867
        gcp->previtem = NULL;
 
3868
        gcp->prevtype = 0;
 
3869
        gcp->parentitem = tparent;
 
3870
        gcp->parenttype = ttype;
 
3871
        gcp->thisitem = (Pointer)sbp;
 
3872
        gcp->thistype = OBJ_SUBMIT_BLOCK;
 
3873
        gcp->prevlink = prevlink;
 
3874
        gcp->itemID = gccp->itemIDs[OBJ_SUBMIT_BLOCK];
 
3875
        GatherAddToStack(gcp);
 
3876
 
 
3877
        if (doit)
 
3878
        {
 
3879
                if (! (*(gccp->userfunc))(gcp))
 
3880
                        return FALSE;
 
3881
                if (LocateItem) return FALSE;
 
3882
                if (LocateData != NULL) return FALSE;
 
3883
        }
 
3884
 
 
3885
        gcp->indent++;
 
3886
 
 
3887
        if (! GatherSeqSubContact(gccp, sbp->contact, OBJ_SUBMIT_BLOCK,
 
3888
                                                                                (Pointer)sbp, (Pointer PNTR)&(sbp->contact)))
 
3889
                return FALSE;
 
3890
 
 
3891
        if (! GatherSeqSubCit(gccp, sbp->cit, OBJ_SUBMIT_BLOCK,
 
3892
                                                                                (Pointer)sbp, (Pointer PNTR)&(sbp->cit)))
 
3893
                return FALSE;
 
3894
 
 
3895
    gcp->indent--;
 
3896
        return TRUE;
 
3897
}
 
3898
 
 
3899
 
 
3900
static Boolean NEAR GatherSeqSubmit (InternalGCCPtr gccp, SeqSubmitPtr ssp, Boolean in_scope)
 
3901
{
 
3902
        GatherContextPtr gcp;
 
3903
        GatherScopePtr gsp;
 
3904
        Boolean takeit=TRUE, tscope, checkscope;
 
3905
        SeqEntryPtr sep, prevsep = NULL, scope = NULL;
 
3906
        Int2 LocateItem = 0;
 
3907
        Pointer LocateData = NULL;
 
3908
        Uint1 thistype;
 
3909
        Pointer PNTR prevlink;
 
3910
 
 
3911
        if (ssp == NULL)
 
3912
                return TRUE;
 
3913
 
 
3914
        gcp = &(gccp->gc);
 
3915
        gsp = &(gccp->scope);
 
3916
 
 
3917
        if (gsp->ignore[OBJ_SEQSUB])
 
3918
                takeit = FALSE;
 
3919
        else if (! in_scope)
 
3920
                takeit = FALSE;
 
3921
 
 
3922
        scope = gsp->scope;
 
3923
        if ((scope != NULL) && (! in_scope))
 
3924
                checkscope = TRUE;
 
3925
        else
 
3926
                checkscope = FALSE;
 
3927
                
 
3928
        gccp->itemIDs[OBJ_SEQSUB]++;
 
3929
        gcp->itemID = gccp->itemIDs[OBJ_SEQSUB];
 
3930
 
 
3931
        if (gccp->locatetype == OBJ_SEQSUB)
 
3932
        {
 
3933
                if ((gccp->locateID == gccp->itemIDs[OBJ_SEQSUB]) ||
 
3934
                        (gccp->locatePtr == (Pointer)ssp))
 
3935
                {
 
3936
                        takeit = TRUE;
 
3937
                        LocateItem = gccp->locateID;
 
3938
                        LocateData = gccp->locatePtr;
 
3939
                }
 
3940
        }
 
3941
 
 
3942
        thistype = OBJ_SEQSUB;
 
3943
        gcp->thistype = thistype;
 
3944
        gcp->thisitem = (Pointer)ssp;
 
3945
        GatherAddToStack(gcp);
 
3946
 
 
3947
        if (takeit)
 
3948
        {
 
3949
                gcp->sep = NULL;
 
3950
                gcp->previtem = NULL;
 
3951
                gcp->prevtype = 0;
 
3952
                gcp->parentitem = NULL;
 
3953
                gcp->parenttype = 0;
 
3954
                gcp->thisitem = (Pointer)ssp;
 
3955
                gcp->thistype = thistype;
 
3956
                gcp->prevlink = NULL;
 
3957
 
 
3958
 
 
3959
                if (! (*(gccp->userfunc))(gcp))
 
3960
                        return FALSE;
 
3961
                if (LocateItem) return FALSE;
 
3962
                if (LocateData != NULL) return FALSE;
 
3963
        }
 
3964
    
 
3965
    gcp->indent++;
 
3966
        if (! GatherSubBlock(gccp, ssp->sub, thistype, (Pointer)ssp,
 
3967
                               (Pointer PNTR)&(ssp->sub)))
 
3968
                return FALSE;
 
3969
    
 
3970
        tscope = in_scope;
 
3971
        prevlink = (Pointer PNTR)&(ssp->data);
 
3972
 
 
3973
        switch(ssp->datatype)
 
3974
        {
 
3975
                case 1:    /* Seq-entrys */
 
3976
                        prevsep = NULL;
 
3977
                        for (sep = (SeqEntryPtr)(ssp->data); sep != NULL; sep = sep->next)
 
3978
                        {
 
3979
                                gcp->previtem = prevsep;
 
3980
                                gcp->prevtype = OBJ_SEQENTRY;
 
3981
                                gcp->parentitem = (Pointer)ssp;
 
3982
                                gcp->parenttype = thistype;
 
3983
                                gcp->prevlink = prevlink;
 
3984
 
 
3985
                                if (checkscope)
 
3986
                                {
 
3987
                                        if (sep == scope)
 
3988
                                                tscope = TRUE;
 
3989
                                        else
 
3990
                                                tscope = FALSE;
 
3991
                                }
 
3992
 
 
3993
                                if (! GatherSeqEntryFunc(sep, gccp, (Pointer)ssp, OBJ_SEQSUB, prevsep, tscope, prevlink))
 
3994
                                        return FALSE;
 
3995
 
 
3996
                                if (checkscope)
 
3997
                                {
 
3998
                                        if (tscope == TRUE)  /* just found it */
 
3999
                                        {
 
4000
                                                checkscope = FALSE;   /* don't look anymore */
 
4001
                                                tscope = FALSE;       /* the siblings not in scope */
 
4002
                                                gsp->scope = NULL;    /* no more to look */
 
4003
                                        }
 
4004
                                        else if (gsp->scope == NULL)   /* found lower down */
 
4005
                                        {
 
4006
                                                checkscope = FALSE;
 
4007
                                                tscope = FALSE;
 
4008
                                        }
 
4009
                                }
 
4010
 
 
4011
                                prevsep = sep;
 
4012
                                prevlink = (Pointer PNTR)&(sep->next);
 
4013
                        }
 
4014
                        break;
 
4015
                case 2:    /* Seq-annots */
 
4016
                        if (! GatherSeqAnnot(gccp, (SeqAnnotPtr)(ssp->data), thistype,
 
4017
                                                (Pointer)ssp,(Pointer PNTR)&(ssp->data), in_scope))
 
4018
                                return FALSE;
 
4019
 
 
4020
                        break;
 
4021
                case 3:    /* SeqIds */
 
4022
                        if (! GatherSeqIds(gccp, (SeqIdPtr)(ssp->data), thistype,
 
4023
                                                (Pointer)ssp,(Pointer PNTR)&(ssp->data)))
 
4024
                                return FALSE;
 
4025
 
 
4026
                        break;
 
4027
                default:
 
4028
                        break;
 
4029
        }
 
4030
        gcp->indent--;  /* reset to original indent level */
 
4031
        return TRUE;
 
4032
}
 
4033
 
 
4034
/*****************************************************************************
 
4035
*
 
4036
*   GatherBioseqPartsFunc(gccp, top)
 
4037
*      gets parts not contained in "top" for segmented entry
 
4038
*
 
4039
*****************************************************************************/
 
4040
static Boolean NEAR GatherBioseqPartsFunc (InternalGCCPtr gccp, Pointer top)
 
4041
{
 
4042
        GatherContextPtr gcp;
 
4043
        GatherScopePtr gsp, tgsp;
 
4044
        GatherScope scopebuf;
 
4045
        SeqLocPtr slp, head;
 
4046
        SeqIdPtr sip;
 
4047
        Boolean retval;
 
4048
        BioseqPtr tbsp;
 
4049
        SeqEntryPtr sep;
 
4050
        Int4 len;
 
4051
        Int2 ctr;
 
4052
        Boolean doit;
 
4053
 
 
4054
        gcp = &(gccp->gc);
 
4055
        gsp = &(gccp->scope);
 
4056
 
 
4057
        if (gsp->seglevels <= gsp->currlevel)
 
4058
                return TRUE;
 
4059
 
 
4060
 
 
4061
        head = gccp->segloc;
 
4062
 
 
4063
        tgsp = &scopebuf;
 
4064
        MemCopy(tgsp, gsp, sizeof(GatherScope));
 
4065
        tgsp->seglevels--;
 
4066
        tgsp->scope = NULL;
 
4067
        tgsp->currlevel++;
 
4068
        tgsp->ignore [OBJ_BIOSEQ] = TRUE;
 
4069
 
 
4070
        slp = NULL;
 
4071
        
 
4072
        retval = FALSE; /*??*/
 
4073
        ctr = 0;
 
4074
        while ((slp = SeqLocFindNext(head, slp)) != NULL)
 
4075
        {
 
4076
                doit = FALSE;
 
4077
                tgsp->target = slp;
 
4078
                sip = SeqLocId(slp);
 
4079
                tbsp = BioseqLockById(sip);
 
4080
                len = SeqLocLen(slp);
 
4081
 
 
4082
                if (len >= 0 && tbsp != NULL)
 
4083
                {
 
4084
                        doit = TRUE;
 
4085
                        if ((gsp->stop_on_annot) && (ctr < gccp->segcnt))
 
4086
                        {
 
4087
                                if (gccp->found_annot[ctr])  /* already found annot here */
 
4088
                                        doit = FALSE;
 
4089
                        }
 
4090
                }
 
4091
 
 
4092
                if (doit)
 
4093
                {
 
4094
                        if (! ObjMgrIsChild(top, (Pointer)tbsp)) /* in set we just did? */
 
4095
                        {
 
4096
                                sep = SeqEntryFind(sip);
 
4097
                                retval = GatherSeqEntry(sep, gcp->userdata, gccp->userfunc, tgsp);
 
4098
                        }
 
4099
                        BioseqUnlock(tbsp);
 
4100
                        if (! retval)
 
4101
                                return FALSE;
 
4102
                }
 
4103
                else if (tbsp != NULL)
 
4104
                        BioseqUnlock(tbsp);
 
4105
                
 
4106
                tgsp->offset += len;
 
4107
                ctr++;
 
4108
        }
 
4109
 
 
4110
        return TRUE;
 
4111
}
 
4112
 
 
4113
static Boolean WholeLocOnBioseq (BioseqPtr bsp, SeqLocPtr slp)
 
4114
 
 
4115
{
 
4116
  SeqIntPtr sintp;
 
4117
  SeqIdPtr  sip;
 
4118
 
 
4119
  if (bsp == NULL || slp == NULL) return FALSE;
 
4120
 
 
4121
  sip = SeqLocId (slp);
 
4122
  if (sip == NULL) return FALSE;
 
4123
  if (! SeqIdIn (sip, bsp->id)) return FALSE;
 
4124
 
 
4125
  if (slp->choice == SEQLOC_WHOLE) return TRUE;
 
4126
  if (slp->choice == SEQLOC_INT) {
 
4127
    sintp = (SeqIntPtr) slp->data.ptrvalue;
 
4128
    if (sintp != NULL &&
 
4129
        sintp->from == 0 &&
 
4130
        sintp->to == bsp->length - 1) return TRUE;
 
4131
  }
 
4132
 
 
4133
  return FALSE;
 
4134
}
 
4135
 
 
4136
static Boolean NEAR IGCCBuild (InternalGCCPtr ip, ObjMgrDataPtr omdp, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
 
4137
{
 
4138
        Boolean in_scope = TRUE;
 
4139
        SeqIdPtr sip;
 
4140
        BioseqPtr bsp = NULL;
 
4141
        ValNode fake;
 
4142
        SeqLocPtr slp;
 
4143
        Int2 ctr;
 
4144
        SeqEntryPtr oldsep;
 
4145
        ObjMgrDataPtr newomdp = NULL;
 
4146
        Boolean reload_from_cache = TRUE;   /* default behavior */
 
4147
        DeltaSeqPtr dsp;
 
4148
        SeqLocPtr loc = NULL;
 
4149
        Uint2 entityID;
 
4150
 
 
4151
        if ((omdp == NULL) || (userfunc == NULL)) return FALSE;
 
4152
 
 
4153
        MemSet((Pointer)(ip), 0, sizeof(InternalGCC));
 
4154
 
 
4155
 
 
4156
        if (scope != NULL)  /* check for turning off reload from cache */
 
4157
        {
 
4158
                if (scope->do_not_reload_from_cache)
 
4159
                        reload_from_cache = FALSE;
 
4160
        }
 
4161
 
 
4162
        if ((omdp->tempload == TL_CACHED) && (reload_from_cache))  /* must reload from cache */
 
4163
        {
 
4164
                newomdp = BioseqReload(omdp, TRUE);
 
4165
                if (newomdp == NULL)
 
4166
                {
 
4167
                        ErrPostEx(SEV_ERROR,0,0,"IGCCBuild: Couldn't reload data from cache.");
 
4168
                        return FALSE;
 
4169
                }
 
4170
                ip->reloaded = TRUE;
 
4171
                omdp = newomdp;
 
4172
 
 
4173
                if (scope != NULL)
 
4174
                {
 
4175
                        if(scope->scope != NULL)
 
4176
                        {
 
4177
                                ErrPostEx(SEV_ERROR,0,0,"IGCCBuild: Scope invalid, data reloaded from cache.");
 
4178
                                ObjMgrLock(omdp->datatype, omdp->dataptr, FALSE);
 
4179
                                return FALSE;
 
4180
                        }
 
4181
                }
 
4182
        }
 
4183
        else
 
4184
                ObjMgrLock(omdp->datatype, omdp->dataptr, TRUE);  /* just lock it */
 
4185
 
 
4186
        ip->omdp = omdp;
 
4187
        ip->gc.userdata = userdata;
 
4188
        ip->userfunc = userfunc;
 
4189
        if (scope != NULL)
 
4190
                MemCopy(&(ip->scope), scope, sizeof(GatherScope));
 
4191
        ip->gc.entityID = omdp->EntityID;
 
4192
        ip->gc.tempload = omdp->tempload;
 
4193
        ip->gc.seglevel = ip->scope.currlevel;
 
4194
        ip->gc.igccp = (Pointer)ip;
 
4195
        if (ObjMgrCheckHold())
 
4196
                ip->gc.hold = TRUE;
 
4197
 
 
4198
        if (ip->scope.target != NULL)
 
4199
        {
 
4200
                sip = SeqLocId(ip->scope.target);
 
4201
 
 
4202
                /* first check if target in the SeqEntry -- necessary if multiple versions with same id */
 
4203
                if ((omdp->choicetype == OBJ_SEQENTRY && omdp->choice != NULL) ||
 
4204
                    (scope != NULL && scope->scope != NULL))
 
4205
                {
 
4206
                        oldsep = SeqEntryGetScope();  /* save any current scope */
 
4207
                        if (omdp->choicetype == OBJ_SEQENTRY) {
 
4208
                                SeqEntrySetScope(omdp->choice);
 
4209
                        } else {
 
4210
                                SeqEntrySetScope(scope->scope);
 
4211
                        }
 
4212
                        bsp = BioseqFindCore(sip);
 
4213
                        if (bsp != NULL)    /* yes it is in here */
 
4214
                                bsp = BioseqLockById(sip);
 
4215
                        SeqEntrySetScope(oldsep);
 
4216
                }
 
4217
 
 
4218
                if (bsp == NULL)                          /* out of scope? */
 
4219
                        bsp = BioseqLockById(sip);/* try again */
 
4220
 
 
4221
                ip->bsp = bsp;
 
4222
                if (SeqLocStrand(ip->scope.target) == Seq_strand_minus)
 
4223
                        ip->rev = TRUE;
 
4224
                if ((ip->scope.seglevels > ip->scope.currlevel)
 
4225
                        && (bsp != NULL))     /* get seg parts? */
 
4226
                {
 
4227
                        slp = NULL;
 
4228
                        loc = NULL;
 
4229
                        if (bsp->repr == Seq_repr_seg)
 
4230
                        {
 
4231
                                fake.choice = SEQLOC_MIX;
 
4232
                                fake.next = NULL;
 
4233
                                fake.data.ptrvalue = bsp->seq_ext;
 
4234
                                slp = &fake;
 
4235
                        } else if (bsp->repr == Seq_repr_delta && bsp->seq_ext_type == 4) {
 
4236
                                dsp = (DeltaSeqPtr) bsp->seq_ext;
 
4237
                                loc = DeltaSeqsToSeqLocs (dsp);
 
4238
                                slp = loc;
 
4239
                        }
 
4240
                        else if (bsp->repr == Seq_repr_ref)
 
4241
                                slp = (SeqLocPtr)(bsp->seq_ext);
 
4242
 
 
4243
                        ip->segloc = SeqLocCopyPart(slp, SeqLocStart(ip->scope.target),
 
4244
                                SeqLocStop(ip->scope.target), SeqLocStrand(ip->scope.target),
 
4245
                                TRUE, &(ip->first_seg), &(ip->last_seg));
 
4246
 
 
4247
                        if (ip->scope.stop_on_annot)
 
4248
                        {
 
4249
 
 
4250
                                slp = NULL; ctr = 0;
 
4251
                                while ((slp = SeqLocFindNext(ip->segloc, slp)) != NULL)
 
4252
                                        ctr++;
 
4253
                                if (ctr)
 
4254
                                {
 
4255
                                        ip->segcnt = ctr;
 
4256
                                        ip->seglens = MemNew((size_t)(sizeof(Int4) * ctr));
 
4257
                                        ip->found_annot = MemNew((size_t)(sizeof(Boolean) * ctr));
 
4258
 
 
4259
                                        slp = NULL; ctr = 0;
 
4260
                                        while ((slp = SeqLocFindNext(ip->segloc, slp)) != NULL)
 
4261
                                        {
 
4262
                                                ip->seglens[ctr] = SeqLocLen(slp);
 
4263
                                                if (ip->seglens[ctr] < 0)
 
4264
                                                        ip->seglens[ctr] = 0;
 
4265
                                                ctr++;
 
4266
                                        }
 
4267
                                }
 
4268
                        }
 
4269
                        loc = SeqLocFree (loc);
 
4270
                }
 
4271
 
 
4272
                /* if targeted gather, try to use feature indexing for speed */
 
4273
                if (bsp != NULL && bsp->repr == Seq_repr_raw &&
 
4274
                        SeqMgrGetParentOfPart (bsp, NULL) == NULL &&
 
4275
                        ip->segloc == NULL && ip->scope.useSeqMgrIndexes &&
 
4276
                        (ip->scope.get_feats_location || ip->scope.get_feats_product) &&
 
4277
                        (! (ip->scope.ignore [OBJ_SEQFEAT]))) {
 
4278
 
 
4279
                        /* target must be whole or full length interval on bioseq */
 
4280
                        if (! WholeLocOnBioseq (bsp, ip->scope.target)) return TRUE;
 
4281
 
 
4282
                        entityID = ObjMgrGetEntityIDForPointer (bsp);
 
4283
 
 
4284
                        /* index features if not already done */
 
4285
                        if (SeqMgrFeaturesAreIndexed (entityID) == 0) {
 
4286
                                SeqMgrIndexFeatures (entityID, NULL);
 
4287
                        }
 
4288
 
 
4289
                        if (SeqMgrFeaturesAreIndexed (entityID) != 0) {
 
4290
                                ip->useSeqMgrIndexes = TRUE;
 
4291
                        }
 
4292
                }
 
4293
        }
 
4294
 
 
4295
        return TRUE;
 
4296
}
 
4297
 
 
4298
NLM_EXTERN AlignDataPtr FreeAlignData(AlignDataPtr adp)
 
4299
{
 
4300
        AlignDataPtr next;
 
4301
        AlignRangePtr arp, arp_next;
 
4302
        
 
4303
        while(adp)
 
4304
        {
 
4305
                arp = adp->arp;
 
4306
                while(arp)
 
4307
                {
 
4308
                        arp_next = arp->next;
 
4309
                        arp->next = NULL;
 
4310
                        MemFree(arp);
 
4311
                        arp = arp_next;
 
4312
                }
 
4313
                next = adp->next;
 
4314
                adp->next = NULL;
 
4315
                MemFree(adp);
 
4316
                adp = next;
 
4317
        }
 
4318
        return NULL;
 
4319
}
 
4320
        
 
4321
        
 
4322
static Boolean IGCCclear(InternalGCCPtr ip)
 
4323
{
 
4324
        if (ip == NULL) return TRUE;
 
4325
 
 
4326
        BioseqUnlock(ip->bsp);
 
4327
        ObjMgrLock(ip->omdp->datatype, ip->omdp->dataptr, FALSE);  /* unlock the entity */
 
4328
 
 
4329
        MemFree(ip->gc.rdp);
 
4330
        FreeAlignData(ip->gc.adp);
 
4331
        ip->gc.adp = NULL;
 
4332
        SeqLocFree(ip->segloc);
 
4333
        MemFree(ip->seglens);
 
4334
        MemFree(ip->found_annot);
 
4335
        MemFree(ip->gc.gatherstack);
 
4336
        MemFree(ip->gc.extra_loc);
 
4337
 
 
4338
        return TRUE;
 
4339
}
 
4340
 
 
4341
static void GatherEntityFunc (ObjMgrDataPtr omdp, InternalGCCPtr gccp, Boolean in_scope)
 
4342
{
 
4343
        ValNodePtr vnp;
 
4344
        Pointer ptr;
 
4345
 
 
4346
        vnp = omdp->choice;
 
4347
        ptr = omdp->dataptr;
 
4348
 
 
4349
        switch (omdp->choicetype)
 
4350
        {
 
4351
                case OBJ_SEQENTRY:
 
4352
                        GatherSeqEntryFunc(vnp, gccp, NULL, 0, NULL, in_scope, NULL);
 
4353
                        break;
 
4354
 
 
4355
                default:
 
4356
                        switch (omdp->datatype)
 
4357
                        {
 
4358
                                case OBJ_BIOSEQ:
 
4359
                                        GatherBioseqFunc(gccp, (BioseqPtr)ptr, NULL, 0, NULL, NULL,
 
4360
                                                NULL, in_scope);
 
4361
                                        break;
 
4362
 
 
4363
                                case OBJ_BIOSEQSET:
 
4364
                                        GatherBioseqSetFunc(gccp, (BioseqSetPtr)ptr, NULL, 0, NULL,
 
4365
                                                in_scope, NULL, NULL);
 
4366
                                        break;
 
4367
 
 
4368
                                case OBJ_SEQDESC:
 
4369
                                        GatherSeqDescr(gccp, (ValNodePtr)ptr, 0, NULL, NULL,in_scope);
 
4370
                                        break;
 
4371
 
 
4372
                                case OBJ_SEQANNOT:
 
4373
                                        GatherSeqAnnot(gccp, (SeqAnnotPtr)ptr, 0,NULL,NULL, in_scope);
 
4374
                                        break;
 
4375
 
 
4376
                                case OBJ_ANNOTDESC:              /* NOT SUPPORTED YET */
 
4377
                                        break;
 
4378
 
 
4379
                                case OBJ_SEQFEAT:
 
4380
                                        GatherSeqFeat(gccp, (SeqFeatPtr)ptr, 0, NULL, NULL, in_scope, OBJ_SEQFEAT);
 
4381
                                        break;
 
4382
 
 
4383
                                case OBJ_SEQALIGN:
 
4384
                                        GatherSeqAlign(gccp, (SeqAlignPtr)ptr, 0, NULL, NULL, in_scope, TRUE, OBJ_SEQALIGN);
 
4385
                                        break;
 
4386
 
 
4387
                                case OBJ_SEQHIST_ALIGN:
 
4388
                                        GatherSeqAlign(gccp, (SeqAlignPtr)ptr, 0, NULL, NULL, in_scope, TRUE, OBJ_SEQHIST_ALIGN);
 
4389
                                        break;
 
4390
 
 
4391
                                case OBJ_SEQGRAPH:
 
4392
                                        GatherSeqGraph(gccp, (SeqGraphPtr)ptr, 0, NULL, NULL, in_scope);
 
4393
                                        break;
 
4394
 
 
4395
                                case OBJ_SEQSUB:
 
4396
                                        GatherSeqSubmit (gccp, (SeqSubmitPtr) ptr, in_scope);
 
4397
                                        break;
 
4398
 
 
4399
                                case OBJ_SUBMIT_BLOCK:
 
4400
                                        GatherSubBlock(gccp, (SubmitBlockPtr)ptr,0,NULL,NULL);
 
4401
                                        break;
 
4402
 
 
4403
                                case OBJ_SEQSUB_CONTACT:
 
4404
                                        GatherSeqSubContact(gccp, (ContactInfoPtr)ptr,0, NULL, NULL);
 
4405
                                        break;
 
4406
 
 
4407
                                case OBJ_BIOSEQ_MAPFEAT:        /* NOT SUPPORTED YET */
 
4408
                                        break;
 
4409
 
 
4410
                                case OBJ_BIOSEQ_SEG:                    /* NOT SEPARATELY SUPPORTED */
 
4411
                                        break;
 
4412
 
 
4413
                                case OBJ_SEQHIST:                       /* NOT SEPARATELY SUPPORTED */
 
4414
                                        GatherSeqHist(gccp, (SeqHistPtr)ptr, 0, NULL, NULL, in_scope, TRUE);
 
4415
                                        break;
 
4416
 
 
4417
                                case OBJ_PUB:
 
4418
                                        GatherPub(gccp, (ValNodePtr)ptr, 0, 0, NULL,NULL, in_scope);
 
4419
                                        break;
 
4420
 
 
4421
                                case OBJ_SEQFEAT_CIT:                   /* NOT SEPARATELY SUPPORTED */
 
4422
                                        break;
 
4423
 
 
4424
                                case OBJ_SEQSUB_CIT:
 
4425
                                        GatherSeqSubCit(gccp, (CitSubPtr)ptr,0, NULL, NULL);
 
4426
                                        break;
 
4427
 
 
4428
                                case OBJ_PUB_SET:
 
4429
                                        GatherPubSet(gccp, (ValNodePtr)ptr, 0, 0, NULL,NULL, in_scope);
 
4430
                                        break;
 
4431
 
 
4432
                                case OBJ_SEQID:
 
4433
                                        GatherSeqIds(gccp, (SeqIdPtr)ptr,0,NULL,NULL);
 
4434
                                        break;
 
4435
 
 
4436
                                default:
 
4437
                                        break;
 
4438
                        }
 
4439
        }
 
4440
 
 
4441
 
 
4442
}
 
4443
/*****************************************************************************
 
4444
*
 
4445
*   FocusSeqEntry (sep, scope)
 
4446
*      zeros out all fields in scope
 
4447
*      sets scope.target, .scope, .propagate_desciptors appropriately for 
 
4448
*         SeqEntry
 
4449
*      if (Bioseq)
 
4450
*         target is the bioseq
 
4451
*         entityID is the containing set if any
 
4452
*         scope.scope is null
 
4453
*      if (BioseqSet)
 
4454
*         target is NULL
 
4455
*         entityID is the containing set if any
 
4456
*         scope.scope is sep
 
4457
*         propagate_descriptors is TRUE
 
4458
*
 
4459
*      return of FOCUS_INITIALIZED means scope is initialized
 
4460
*      return of FOCUS_NOT_NEEDED means send NULL for GatherScope.. you
 
4461
*        don't need to scope for this SeqEntryPtr
 
4462
*      return of FOCUS_ERROR  means it could not be initialized
 
4463
*
 
4464
*****************************************************************************/
 
4465
NLM_EXTERN Int2 LIBCALL FocusSeqEntry (SeqEntryPtr sep, GatherScopePtr scope)
 
4466
{
 
4467
        Int2 retval = FOCUS_ERROR;
 
4468
        ObjMgrDataPtr omdp;
 
4469
        ObjMgrPtr omp;
 
4470
        SeqIdPtr sip;
 
4471
        SeqLocPtr slp;
 
4472
        BioseqPtr bsp;
 
4473
 
 
4474
        if ((sep == NULL) || (scope == NULL))
 
4475
                return retval;
 
4476
 
 
4477
        MemSet((Pointer)scope, 0, sizeof(GatherScope));
 
4478
 
 
4479
        omp = ObjMgrReadLock();
 
4480
        omdp = ObjMgrFindByData(omp, sep->data.ptrvalue);
 
4481
        if (omdp == NULL) goto erret;
 
4482
 
 
4483
        if (omdp->parentptr == NULL)
 
4484
        {
 
4485
                retval = FOCUS_NOT_NEEDED;
 
4486
                goto erret;
 
4487
        }
 
4488
 
 
4489
        if (IS_Bioseq(sep))
 
4490
        {
 
4491
                slp = ValNodeNew(NULL);
 
4492
                slp->choice = SEQLOC_WHOLE;
 
4493
                bsp = (BioseqPtr) sep->data.ptrvalue;
 
4494
                sip = SeqIdDup (SeqIdFindBest (bsp->id, 0));
 
4495
                slp->data.ptrvalue = sip;
 
4496
                scope->target = slp;
 
4497
        }
 
4498
        else
 
4499
        {
 
4500
                scope->scope = sep;
 
4501
                omdp = ObjMgrFindTop(omp, omdp);
 
4502
                if (omdp->tempload == TL_CACHED)
 
4503
                {
 
4504
                        ErrPostEx(SEV_ERROR, 0,0, "FocusSeqEntry: Scope to BioseqSet on Cached record");
 
4505
                        goto erret;
 
4506
                }
 
4507
        }
 
4508
        retval = FOCUS_INITIALIZED;
 
4509
erret:
 
4510
        ObjMgrUnlock();
 
4511
        return retval;
 
4512
}
 
4513
 
 
4514
/*****************************************************************************
 
4515
*
 
4516
*   GatherSeqEntry (sep, userdata, userproc, scope)
 
4517
*
 
4518
*****************************************************************************/
 
4519
NLM_EXTERN Boolean LIBCALL GatherSeqEntry (SeqEntryPtr sep, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
 
4520
{
 
4521
        Uint2 entityID;
 
4522
 
 
4523
        if ((sep == NULL) || (userfunc == NULL)) return FALSE;
 
4524
 
 
4525
        entityID = ObjMgrGetEntityIDForChoice(sep);
 
4526
        
 
4527
        return GatherEntity (entityID, userdata, userfunc, scope);
 
4528
}
 
4529
 
 
4530
/*****************************************************************************
 
4531
*
 
4532
*   GatherEntity (entityID, userdata, userproc, scope)
 
4533
*
 
4534
*****************************************************************************/
 
4535
NLM_EXTERN Boolean LIBCALL GatherEntity (Uint2 entityID, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
 
4536
{
 
4537
        InternalGCC igcc;
 
4538
        Boolean in_scope;
 
4539
        ObjMgrDataPtr omdp;
 
4540
        Boolean reloaded_from_cache = FALSE;
 
4541
        ObjMgrPtr omp;
 
4542
 
 
4543
        if ((! entityID) || (userfunc == NULL)) return FALSE;
 
4544
 
 
4545
        omp = ObjMgrReadLock();
 
4546
        omdp = ObjMgrGetDataStruct (omp, entityID);
 
4547
        ObjMgrUnlock();
 
4548
 
 
4549
        if (omdp == NULL) return FALSE;
 
4550
 
 
4551
        if (! IGCCBuild(&igcc, omdp, userdata, userfunc, scope))
 
4552
                return FALSE;
 
4553
 
 
4554
        omdp = igcc.omdp;   /* could have been reloaded */
 
4555
        if (igcc.scope.scope != NULL)
 
4556
        {
 
4557
                        in_scope = ObjMgrIsChild((igcc.scope.scope->data.ptrvalue), (omdp->dataptr));
 
4558
        }
 
4559
        else                   /* no scope set.. all in scope */
 
4560
                in_scope = TRUE;
 
4561
 
 
4562
        GatherEntityFunc(omdp, &igcc, in_scope);
 
4563
 
 
4564
        if ((igcc.segloc != NULL) && (igcc.scope.scope == NULL)) /* get segs first */
 
4565
                GatherBioseqPartsFunc(&igcc, omdp->dataptr);
 
4566
 
 
4567
 
 
4568
        return IGCCclear(&igcc);
 
4569
}
 
4570
/**************************************************************************
 
4571
*
 
4572
*   callback used by GatherItemIDByData
 
4573
*
 
4574
***************************************************************************/
 
4575
static Boolean GatherItemByDataProc (GatherContextPtr gcp)
 
4576
{
 
4577
        Uint2Ptr ptr;
 
4578
 
 
4579
        ptr = (Uint2Ptr)(gcp->userdata);
 
4580
        *ptr = gcp->itemID;
 
4581
 
 
4582
        return TRUE;
 
4583
}
 
4584
 
 
4585
/*****************************************************************************
 
4586
*
 
4587
*   GatherItemIDByData (entityID, itemtype, dataptr)
 
4588
*      Looks in entityID for an element of itemtype that matches the pointer
 
4589
*         dataptr.
 
4590
*      if found, returns the itemID
 
4591
*      else returns 0
 
4592
*      itemtype is as defined in objmgr.h for OBJ_
 
4593
*
 
4594
*****************************************************************************/
 
4595
NLM_EXTERN Uint2 LIBCALL GatherItemIDByData (Uint2 entityID, Uint2 itemtype, Pointer dataptr)
 
4596
{
 
4597
        Uint2 itemID = 0;
 
4598
 
 
4599
        GatherData(entityID, dataptr, itemtype, (Pointer)(&itemID), GatherItemByDataProc);
 
4600
        return itemID;
 
4601
}
 
4602
 
 
4603
 
 
4604
/*****************************************************************************
 
4605
*
 
4606
*   GatherData (entityID, itemID, itemtype, userdata, userproc)
 
4607
*      Get an item by entityID, itemtype, and a Pointer of itemtype
 
4608
*      GatherContext.seglevel and GatherContext.propagated will not be
 
4609
*        set on the callback.
 
4610
*   
 
4611
*      Sets in_scope to FALSE so that the callback is not called
 
4612
*         Scope is NULL, so in_scope is never TRUE
 
4613
*      Sets ignore TRUE for everything not needed to find item
 
4614
*      Sets locatetype and locateID, which are checked in the traversal
 
4615
*
 
4616
*****************************************************************************/
 
4617
NLM_EXTERN Boolean LIBCALL GatherData (Uint2 entityID, Pointer dataptr, Uint2 itemtype,
 
4618
                                   Pointer userdata, GatherItemProc userfunc)
 
4619
{
 
4620
        return GatherItemFunc (entityID, 0, itemtype, userdata, userfunc, dataptr, FALSE);
 
4621
}
 
4622
 
 
4623
/*****************************************************************************
 
4624
*
 
4625
*   GatherItem (entityID, itemID, itemtype, userdata, userproc)
 
4626
*      Get an item by entityID, itemID, itemtype
 
4627
*      GatherContext.seglevel and GatherContext.propagated will not be
 
4628
*        set on the callback.
 
4629
*   
 
4630
*      Sets in_scope to FALSE so that the callback is not called
 
4631
*         Scope is NULL, so in_scope is never TRUE
 
4632
*      Sets ignore TRUE for everything not needed to find item
 
4633
*      Sets locatetype and locateID, which are checked in the traversal
 
4634
*
 
4635
*****************************************************************************/
 
4636
NLM_EXTERN Boolean LIBCALL GatherItem (Uint2 entityID, Uint2 itemID, Uint2 itemtype,
 
4637
                                   Pointer userdata, GatherItemProc userfunc)
 
4638
{
 
4639
        return GatherItemFunc (entityID, itemID, itemtype, userdata, userfunc, NULL, FALSE);
 
4640
}
 
4641
 
 
4642
/*****************************************************************************
 
4643
*
 
4644
*   GatherItemFunc (entityID, itemID, itemtype, userdata, userproc, dataptr)
 
4645
*      Get an item by entityID, itemID, itemtype if dataptr is NULL
 
4646
*         else it matches entityID, itemtype, dataptr (of type itemtype)
 
4647
*      GatherContext.seglevel and GatherContext.propagated will not be
 
4648
*        set on the callback.
 
4649
*   
 
4650
*      Sets in_scope to FALSE so that the callback is not called
 
4651
*         Scope is NULL, so in_scope is never TRUE
 
4652
*      Sets ignore TRUE for everything not needed to find item
 
4653
*      Sets locatetype and locateID, which are checked in the traversal
 
4654
*
 
4655
*****************************************************************************/
 
4656
static Boolean NEAR GatherItemFunc (Uint2 entityID, Uint2 itemID, Uint2 itemtype,
 
4657
                                   Pointer userdata, GatherItemProc userfunc, Pointer dataptr,
 
4658
                                                                   Boolean do_not_reload_from_cache)
 
4659
 
 
4660
{
 
4661
        InternalGCC igcc;
 
4662
        ObjMgrDataPtr omdp;
 
4663
        GatherScope gs;
 
4664
        ObjMgrPtr omp;
 
4665
 
 
4666
        if (userfunc == NULL) return FALSE;
 
4667
 
 
4668
        if (itemtype >= OBJ_MAX) return FALSE;
 
4669
 
 
4670
        omp = ObjMgrReadLock();
 
4671
        omdp = ObjMgrGetDataStruct(omp, entityID);
 
4672
        ObjMgrUnlock();
 
4673
 
 
4674
        if (omdp == NULL) return FALSE;
 
4675
 
 
4676
        MemSet((Pointer)(&gs), 0, sizeof(GatherScope));
 
4677
        gs.do_not_reload_from_cache = do_not_reload_from_cache;
 
4678
        MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)((OBJ_MAX)*sizeof(Boolean)));
 
4679
        gs.ignore[itemtype] = FALSE;
 
4680
        switch (itemtype)                 /* add higher levels if necessary */
 
4681
        {
 
4682
                case OBJ_SEQFEAT_CIT:
 
4683
                        gs.ignore[OBJ_SEQFEAT] = FALSE;
 
4684
                        gs.ignore[OBJ_PUB_SET] = FALSE;
 
4685
                case OBJ_SEQFEAT:
 
4686
                        gs.ignore[OBJ_SEQANNOT] = FALSE;
 
4687
                        break;
 
4688
                case OBJ_SEQALIGN:
 
4689
                        gs.ignore[OBJ_SEQANNOT] = FALSE;
 
4690
                        break;
 
4691
                case OBJ_SEQHIST_ALIGN:
 
4692
                        gs.ignore[OBJ_SEQHIST] = FALSE;
 
4693
                        break;
 
4694
                case OBJ_SEQGRAPH:
 
4695
                        gs.ignore[OBJ_SEQANNOT] = FALSE;
 
4696
                        break;
 
4697
                case OBJ_SEQSUB_CONTACT:
 
4698
                case OBJ_SEQSUB_CIT:
 
4699
                        gs.ignore[OBJ_SUBMIT_BLOCK] = FALSE;
 
4700
                case OBJ_SUBMIT_BLOCK:
 
4701
                        gs.ignore[OBJ_SEQSUB] = FALSE;
 
4702
                        break;
 
4703
        }
 
4704
 
 
4705
        if (! IGCCBuild(&igcc, omdp, userdata, userfunc, &gs))
 
4706
                return FALSE;
 
4707
 
 
4708
        omdp = igcc.omdp;   /* could have been reloaded */
 
4709
 
 
4710
        igcc.locatetype = (Uint1)itemtype;
 
4711
        igcc.locateID = itemID;
 
4712
        igcc.locatePtr = dataptr;
 
4713
    
 
4714
 
 
4715
        GatherEntityFunc(omdp, &igcc, FALSE);
 
4716
 
 
4717
        return IGCCclear(&igcc);
 
4718
}
 
4719
 
 
4720
typedef struct gatherdatastruct {
 
4721
        OMProcControlPtr ompcp;
 
4722
        Boolean succeeded;
 
4723
} GDS, PNTR GDSPtr;
 
4724
 
 
4725
static Boolean GatherDataProc (GatherContextPtr gcp)
 
4726
{
 
4727
        OMProcControlPtr ompcp;
 
4728
        GDSPtr gdsp;
 
4729
 
 
4730
        gdsp = (GDSPtr)(gcp->userdata);
 
4731
        ompcp = gdsp->ompcp;
 
4732
    
 
4733
    ompcp->input_data = gcp->thisitem;
 
4734
    
 
4735
        switch (gcp->thistype)
 
4736
        {
 
4737
                case OBJ_BIOSEQSET:
 
4738
                case OBJ_BIOSEQ:
 
4739
                        if (gcp->sep != NULL)
 
4740
                        {
 
4741
                                ompcp->input_choice = gcp->sep;
 
4742
                                ompcp->input_choicetype = OBJ_SEQENTRY;
 
4743
                        }
 
4744
                        break;
 
4745
                default:
 
4746
                        break;
 
4747
        }
 
4748
        gdsp->succeeded = TRUE;
 
4749
        return TRUE;
 
4750
}
 
4751
 
 
4752
static Boolean ReplaceDataProc (GatherContextPtr gcp)
 
4753
{
 
4754
        ObjMgrPtr omp;
 
4755
        ObjMgrTypePtr omtp;
 
4756
        ObjMgrDataPtr omdp;
 
4757
        OMProcControlPtr ompcp;
 
4758
        Pointer oldptr, newptr;
 
4759
        GDSPtr gdsp;
 
4760
        SeqEntryPtr sep=NULL;
 
4761
 
 
4762
 
 
4763
        gdsp = (GDSPtr)(gcp->userdata);
 
4764
        ompcp = gdsp->ompcp;
 
4765
        newptr = ompcp->output_data;
 
4766
 
 
4767
    oldptr = gcp->thisitem;
 
4768
 
 
4769
        omp = ObjMgrReadLock();
 
4770
        omtp = ObjMgrTypeFind(omp, gcp->thistype, NULL, NULL);
 
4771
        ObjMgrUnlock();
 
4772
 
 
4773
        if (omtp == NULL)
 
4774
        {
 
4775
                ErrPostEx(SEV_ERROR,0,0,"ReplaceDataProc: can't find type [%d]", (int)gcp->thistype);
 
4776
                return TRUE;
 
4777
        }
 
4778
 
 
4779
        if (! GatherOverWrite(oldptr, newptr, gcp->thistype))   /* overwrite the old data object */
 
4780
                return TRUE;
 
4781
 
 
4782
        if (ompcp->output_entityID)   /* remove with objmgr? */
 
4783
        {
 
4784
                omp = ObjMgrReadLock();
 
4785
                omdp = ObjMgrGetDataStruct (omp, ompcp->output_entityID);
 
4786
                ObjMgrUnlock();
 
4787
 
 
4788
                if (omdp != NULL)
 
4789
                {
 
4790
                        if ((gcp->thistype == OBJ_BIOSEQ) || (gcp->thistype == OBJ_BIOSEQSET))
 
4791
                                sep = omdp->choice;
 
4792
                        if (ObjMgrWholeEntity(omdp, ompcp->output_itemID, ompcp->output_itemtype))
 
4793
                                ObjMgrDelete(ompcp->output_itemtype, ompcp->output_data);
 
4794
                }
 
4795
        }
 
4796
 
 
4797
        if (sep != NULL)
 
4798
                SeqEntryFree(sep);
 
4799
        else
 
4800
                (*(omtp->freefunc))(ompcp->output_data);
 
4801
 
 
4802
        gdsp->succeeded = TRUE;
 
4803
 
 
4804
        return TRUE;
 
4805
}
 
4806
 
 
4807
static Boolean DetachDataProc (GatherContextPtr gcp)
 
4808
{
 
4809
        OMProcControlPtr ompcp;
 
4810
        Pointer next = NULL, ptr;
 
4811
        GDSPtr gdsp;
 
4812
 
 
4813
        gdsp = (GDSPtr)(gcp->userdata);
 
4814
        ompcp = gdsp->ompcp;
 
4815
 
 
4816
    ptr = gcp->thisitem;
 
4817
    ompcp->input_data = ptr;
 
4818
    
 
4819
        switch (gcp->thistype)
 
4820
        {
 
4821
                case OBJ_BIOSEQSET:
 
4822
                case OBJ_BIOSEQ:
 
4823
                        if (gcp->sep != NULL)
 
4824
                        {
 
4825
                                ompcp->input_choice = gcp->sep;
 
4826
                                ompcp->input_choicetype = OBJ_SEQENTRY;
 
4827
                                next = gcp->sep->next;
 
4828
                                gcp->sep->next = NULL;
 
4829
                        }
 
4830
                        break;
 
4831
                case OBJ_SEQDESC:
 
4832
                case OBJ_BIOSEQ_SEG:
 
4833
                case OBJ_PUB:
 
4834
                case OBJ_SEQFEAT_CIT:
 
4835
                case OBJ_PUB_SET:
 
4836
                case OBJ_SEQLOC:
 
4837
                case OBJ_SEQID:
 
4838
                case OBJ_SEQENTRY:
 
4839
                        next = (Pointer)(((ValNodePtr)(ptr))->next);
 
4840
                        (((ValNodePtr)(ptr))->next) = NULL;
 
4841
                        break;
 
4842
                case OBJ_BIOSEQ_MAPFEAT:
 
4843
                case OBJ_SEQFEAT:
 
4844
                        next = (Pointer)(((SeqFeatPtr)(ptr))->next);
 
4845
                        (((SeqFeatPtr)(ptr))->next) = NULL;
 
4846
                        break;
 
4847
                case OBJ_SEQANNOT:
 
4848
                        next = (Pointer)(((SeqAnnotPtr)(ptr))->next);
 
4849
                        (((SeqAnnotPtr)(ptr))->next) = NULL;
 
4850
                        break;
 
4851
                case OBJ_SEQALIGN:
 
4852
                case OBJ_SEQHIST_ALIGN:
 
4853
                        next = (Pointer)(((SeqAlignPtr)(ptr))->next);
 
4854
                        (((SeqAlignPtr)(ptr))->next) = NULL;
 
4855
                        break;
 
4856
                case OBJ_SEQGRAPH:
 
4857
                        next = (Pointer)(((SeqGraphPtr)(ptr))->next);
 
4858
                        (((SeqGraphPtr)(ptr))->next) = NULL;
 
4859
                        break;
 
4860
                default:
 
4861
                        break;
 
4862
        }
 
4863
        if (ompcp->whole_entity)  /* nothing to detach from */
 
4864
                return TRUE;
 
4865
 
 
4866
        if (gcp->prevlink != NULL)
 
4867
                *(gcp->prevlink) = next;
 
4868
 
 
4869
        ObjMgrDetach(gcp->thistype, ptr);
 
4870
 
 
4871
        gdsp->succeeded = TRUE;
 
4872
 
 
4873
        return TRUE;
 
4874
}
 
4875
 
 
4876
static void AddAnAnnot(SeqAnnotPtr PNTR head, Pointer ptr)
 
4877
{
 
4878
        SeqAnnotPtr prev, sap;
 
4879
 
 
4880
        if (head == NULL) return;
 
4881
        sap = (SeqAnnotPtr)ptr;
 
4882
 
 
4883
        if (*head == NULL)
 
4884
        {
 
4885
                *head = sap;
 
4886
                return;
 
4887
        }
 
4888
 
 
4889
        for (prev = (*head); prev->next != NULL; prev = prev->next)
 
4890
                continue;
 
4891
 
 
4892
        prev->next = sap;
 
4893
        return;
 
4894
}
 
4895
 
 
4896
static Boolean AddToSeqAnnot (SeqAnnotPtr sap, Int2 the_type, Pointer addptr)
 
4897
{
 
4898
        SeqFeatPtr sfp;
 
4899
        SeqAlignPtr salp;
 
4900
        SeqGraphPtr sgp;
 
4901
        Pointer PNTR prevlink = NULL;
 
4902
 
 
4903
        if (sap == NULL) return FALSE;
 
4904
 
 
4905
        if (sap->type == 0)
 
4906
                sap->type = (Uint1)the_type;
 
4907
 
 
4908
        if (sap->type != (Uint1)the_type)
 
4909
                return FALSE;
 
4910
 
 
4911
        if (sap->data == NULL)
 
4912
                prevlink = &(sap->data);
 
4913
        else
 
4914
        {
 
4915
                switch (the_type)
 
4916
                {
 
4917
                        case 1:   /* feature table */
 
4918
                                for (sfp = (SeqFeatPtr)(sap->data); sfp->next != NULL; sfp = sfp->next)
 
4919
                                        continue;
 
4920
                                prevlink = (Pointer PNTR)&(sfp->next);
 
4921
                                break;
 
4922
                        case 2:   /* alignments */
 
4923
                                for (salp = (SeqAlignPtr)(sap->data); salp->next != NULL; salp = salp->next)
 
4924
                                        continue;
 
4925
                                prevlink = (Pointer PNTR)&(salp->next);
 
4926
                                break;
 
4927
                        case 3:   /* Graph */
 
4928
                                for (sgp = (SeqGraphPtr)(sap->data); sgp->next != NULL; sgp = sgp->next)
 
4929
                                        continue;
 
4930
                                prevlink = (Pointer PNTR)&(sgp->next);
 
4931
                                break;
 
4932
                }
 
4933
        }
 
4934
        if (prevlink != NULL)
 
4935
                *prevlink = addptr;
 
4936
 
 
4937
        return TRUE;
 
4938
}
 
4939
 
 
4940
static void AddToAnnot(SeqAnnotPtr PNTR head, Int2 the_type, Pointer addptr)
 
4941
{
 
4942
        SeqAnnotPtr sap, prev=NULL;
 
4943
 
 
4944
        if (head == NULL) return;
 
4945
 
 
4946
        for (sap = *head; sap != NULL; sap = sap->next)
 
4947
        {
 
4948
                if (sap->type == the_type)
 
4949
                        break;
 
4950
                prev = sap;
 
4951
        }
 
4952
 
 
4953
        if (sap == NULL)
 
4954
        {
 
4955
                sap = SeqAnnotNew();
 
4956
                sap->type = (Uint1)the_type;
 
4957
                if (prev != NULL)
 
4958
                        prev->next = sap;
 
4959
                else
 
4960
                        *head = sap;
 
4961
        }
 
4962
 
 
4963
        AddToSeqAnnot(sap, the_type, addptr);
 
4964
 
 
4965
        return;
 
4966
}
 
4967
 
 
4968
static ValNodePtr PubFromDescr(ValNodePtr desc)
 
4969
{
 
4970
        ValNodePtr vnp2, vnp;
 
4971
        PubdescPtr pdp;
 
4972
 
 
4973
        if (desc->choice != Seq_descr_pub)
 
4974
                return NULL;
 
4975
 
 
4976
        pdp = (PubdescPtr)(desc->data.ptrvalue);
 
4977
        vnp = pdp->pub;
 
4978
        pdp->pub = NULL;
 
4979
 
 
4980
        SeqDescFree(desc);
 
4981
 
 
4982
        if (vnp == NULL) return vnp;
 
4983
 
 
4984
        if (vnp->next != NULL)
 
4985
        {
 
4986
                vnp2 = vnp;
 
4987
                vnp = ValNodeNew(NULL);
 
4988
                vnp->choice = PUB_Equiv;
 
4989
                vnp->data.ptrvalue = vnp2;
 
4990
        }
 
4991
 
 
4992
        return vnp;
 
4993
}
 
4994
 
 
4995
static ValNodePtr DescrFromPub(ValNodePtr pub)
 
4996
{
 
4997
        ValNodePtr vnp;
 
4998
        PubdescPtr pdp;
 
4999
 
 
5000
        pdp = PubdescNew();
 
5001
        if (pub->choice == PUB_Equiv)
 
5002
        {
 
5003
                vnp = (ValNodePtr)(pub->data.ptrvalue);
 
5004
                MemFree(pub);
 
5005
                pub = vnp;
 
5006
        }
 
5007
        pdp->pub = pub;
 
5008
        vnp = ValNodeNew(NULL);
 
5009
        vnp->choice = Seq_descr_pub;
 
5010
        vnp->data.ptrvalue = (Pointer)pdp;
 
5011
        return vnp;
 
5012
}
 
5013
 
 
5014
static Boolean AttachDataProc (GatherContextPtr gcp)
 
5015
{
 
5016
        OMProcControlPtr ompcp;
 
5017
        Pointer ptr, newptr;
 
5018
        Uint2 into, newtype;
 
5019
        Boolean no_good = FALSE, into_seqentry = FALSE;
 
5020
        ValNodePtr vnp;
 
5021
        ObjMgrDataPtr omdp=NULL;
 
5022
        ObjMgrPtr omp;
 
5023
        BioseqPtr bsp;
 
5024
        BioseqSetPtr bssp;
 
5025
        SeqAnnotPtr sap;
 
5026
        SeqFeatPtr sfp;
 
5027
        SeqAlignPtr salp;
 
5028
        SeqGraphPtr sgp;
 
5029
        SeqSubmitPtr ssp;
 
5030
        SubmitBlockPtr sbp;
 
5031
        GDSPtr gdsp;
 
5032
 
 
5033
        gdsp = (GDSPtr)(gcp->userdata);
 
5034
        ompcp = gdsp->ompcp;
 
5035
 
 
5036
    ptr = gcp->thisitem;   /* insert before or into this */
 
5037
    ompcp->input_data = ptr;
 
5038
 
 
5039
    into = gcp->thistype;
 
5040
        newtype = ompcp->output_itemtype;
 
5041
        newptr = ompcp->output_data;
 
5042
 
 
5043
        omp = ObjMgrWriteLock();
 
5044
        omdp = ObjMgrFindByData(omp, newptr);
 
5045
 
 
5046
        switch (into)
 
5047
        {
 
5048
                case OBJ_BIOSEQSET:
 
5049
                case OBJ_BIOSEQ:
 
5050
                        if (gcp->sep != NULL)
 
5051
                        {
 
5052
                                ompcp->input_choice = gcp->sep;
 
5053
                                ompcp->input_choicetype = OBJ_SEQENTRY;
 
5054
                                into_seqentry = TRUE;
 
5055
                        }
 
5056
                        break;
 
5057
                default:
 
5058
                        break;
 
5059
        }
 
5060
 
 
5061
        switch (into)
 
5062
        {
 
5063
                case OBJ_SEQSUB:
 
5064
                        ssp = (SeqSubmitPtr)(ptr);
 
5065
                        switch (newtype)
 
5066
                        {
 
5067
                                case OBJ_BIOSEQSET:
 
5068
                                case OBJ_BIOSEQ:
 
5069
                                        if (omdp == NULL)
 
5070
                                        {
 
5071
                                                ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
 
5072
                                                return TRUE;
 
5073
                                        }
 
5074
                                        if (ssp->datatype == 0)
 
5075
                                                ssp->datatype = 1;
 
5076
                                        if (ssp->datatype != 1)
 
5077
                                        {
 
5078
                                                no_good = TRUE;
 
5079
                                                break;
 
5080
                                        }
 
5081
                                        if (omdp->choice == NULL)
 
5082
                                        {
 
5083
                                                omdp->choice = ValNodeNew(NULL);
 
5084
                                                omdp->choicetype = OBJ_SEQENTRY;
 
5085
                                                omdp->choice->data.ptrvalue = newptr;
 
5086
                                                if (newtype == OBJ_BIOSEQ)
 
5087
                                                        omdp->choice->choice = 1;
 
5088
                                                else
 
5089
                                                        omdp->choice->choice = 2;
 
5090
                                        }
 
5091
                                        ValNodeLink((ValNodePtr PNTR)&(ssp->data), omdp->choice);
 
5092
                                        ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
 
5093
                                        break;
 
5094
                                case OBJ_PUB:
 
5095
                                        vnp = (ValNodePtr)newptr;
 
5096
                                        no_good = TRUE;
 
5097
                                        if (vnp->choice == PUB_Sub)
 
5098
                                        {
 
5099
                                                if (ssp->sub == NULL)
 
5100
                                                        ssp->sub = SubmitBlockNew();
 
5101
                                                if (ssp->sub->cit == NULL)
 
5102
                                                {
 
5103
                                                        ssp->sub->cit = (CitSubPtr)(vnp->data.ptrvalue);
 
5104
                                                        ValNodeFree(vnp);
 
5105
                                                        no_good = FALSE;
 
5106
                                                }
 
5107
                                        }
 
5108
                                        break;
 
5109
                                case OBJ_SEQENTRY:
 
5110
                                        if (ssp->datatype == 0)
 
5111
                                                ssp->datatype = 1;
 
5112
                                        if (ssp->datatype != 1)
 
5113
                                        {
 
5114
                                                no_good = TRUE;
 
5115
                                                break;
 
5116
                                        }
 
5117
                                        ValNodeLink((ValNodePtr PNTR)&(ssp->data), omdp->choice);
 
5118
                                        ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
 
5119
                                        break;
 
5120
                                case OBJ_SEQANNOT:
 
5121
                                        if (ssp->datatype == 0)
 
5122
                                                ssp->datatype = 2;
 
5123
                                        if (ssp->datatype != 2)
 
5124
                                        {
 
5125
                                                no_good = TRUE;
 
5126
                                                break;
 
5127
                                        }
 
5128
                                        AddAnAnnot((SeqAnnotPtr PNTR)&(ssp->data), newptr);
 
5129
                                        break;
 
5130
                                case OBJ_SEQFEAT:
 
5131
                                        if (ssp->datatype == 0)
 
5132
                                                ssp->datatype = 2;
 
5133
                                        if (ssp->datatype != 2)
 
5134
                                        {
 
5135
                                                no_good = TRUE;
 
5136
                                                break;
 
5137
                                        }
 
5138
                                        AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 1, newptr);
 
5139
                                        break;
 
5140
                                case OBJ_SEQALIGN:
 
5141
                                        if (ssp->datatype == 0)
 
5142
                                                ssp->datatype = 2;
 
5143
                                        if (ssp->datatype != 2)
 
5144
                                        {
 
5145
                                                no_good = TRUE;
 
5146
                                                break;
 
5147
                                        }
 
5148
                                        AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 2, newptr);
 
5149
                                        break;
 
5150
                                case OBJ_SEQGRAPH:
 
5151
                                        if (ssp->datatype == 0)
 
5152
                                                ssp->datatype = 2;
 
5153
                                        if (ssp->datatype != 2)
 
5154
                                        {
 
5155
                                                no_good = TRUE;
 
5156
                                                break;
 
5157
                                        }
 
5158
                                        AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 3, newptr);
 
5159
                                        break;
 
5160
                                case OBJ_SUBMIT_BLOCK:
 
5161
                                        if (ssp->sub == NULL)
 
5162
                                                ssp->sub = (SubmitBlockPtr)newptr;
 
5163
                                        else
 
5164
                                                no_good = TRUE;
 
5165
                                        break;
 
5166
                                case OBJ_SEQSUB_CONTACT:
 
5167
                                        if (ssp->sub == NULL)
 
5168
                                                ssp->sub = SubmitBlockNew();
 
5169
                                        if (ssp->sub->contact == NULL)
 
5170
                                                ssp->sub->contact = (ContactInfoPtr)newptr;
 
5171
                                        else
 
5172
                                                no_good = TRUE;
 
5173
                                        break;
 
5174
                                default:
 
5175
                                        no_good = TRUE;
 
5176
                                        break;
 
5177
                        }
 
5178
                        break;
 
5179
                case OBJ_SUBMIT_BLOCK:
 
5180
                        sbp = (SubmitBlockPtr)(ptr);
 
5181
                        switch (newtype)
 
5182
                        {
 
5183
                                case OBJ_PUB:
 
5184
                                        vnp = (ValNodePtr)newptr;
 
5185
                                        no_good = TRUE;
 
5186
                                        if (vnp->choice == PUB_Sub)
 
5187
                                        {
 
5188
                                                if (sbp->cit == NULL)
 
5189
                                                {
 
5190
                                                        sbp->cit = (CitSubPtr)(vnp->data.ptrvalue);
 
5191
                                                        ValNodeFree(vnp);
 
5192
                                                        no_good = FALSE;
 
5193
                                                }
 
5194
                                        }
 
5195
                                        break;
 
5196
                                case OBJ_SEQSUB_CONTACT:
 
5197
                                        if (sbp->contact == NULL)
 
5198
                                                sbp->contact = (ContactInfoPtr)newptr;
 
5199
                                        else
 
5200
                                                no_good = TRUE;
 
5201
                                        break;
 
5202
                                default:
 
5203
                                        no_good = TRUE;
 
5204
                                        break;
 
5205
                        }
 
5206
                        break;
 
5207
                case OBJ_BIOSEQSET:
 
5208
                        bssp = (BioseqSetPtr)(ptr);
 
5209
                        switch (newtype)
 
5210
                        {
 
5211
                                case OBJ_BIOSEQSET:
 
5212
                                case OBJ_BIOSEQ:
 
5213
                                        if (omdp == NULL)
 
5214
                                        {
 
5215
                                                ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
 
5216
                                                return TRUE;
 
5217
                                        }
 
5218
                                        if (omdp->choice == NULL)
 
5219
                                        {
 
5220
                                                omdp->choice = ValNodeNew(NULL);
 
5221
                                                omdp->choicetype = OBJ_SEQENTRY;
 
5222
                                                omdp->choice->data.ptrvalue = newptr;
 
5223
                                                if (newtype == OBJ_BIOSEQ)
 
5224
                                                        omdp->choice->choice = 1;
 
5225
                                                else
 
5226
                                                        omdp->choice->choice = 2;
 
5227
                                        }
 
5228
                                        ValNodeLink(&(bssp->seq_set), omdp->choice);
 
5229
                                        ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
 
5230
                                        break;
 
5231
                                case OBJ_SEQDESC:
 
5232
                                        ValNodeLink(&(bssp->descr), (ValNodePtr)newptr);
 
5233
                                        break;
 
5234
                                case OBJ_PUB:                      /* make a pubdesc */
 
5235
                                case OBJ_SEQFEAT_CIT:
 
5236
                                        vnp = DescrFromPub((ValNodePtr)newptr);
 
5237
                                        ValNodeLink(&(bssp->descr), vnp);
 
5238
                                        break;
 
5239
                                case OBJ_SEQENTRY:
 
5240
                                        ValNodeLink(&(bssp->seq_set), newptr);
 
5241
                                        break;
 
5242
                                case OBJ_SEQANNOT:
 
5243
                                        AddAnAnnot(&(bssp->annot), newptr);
 
5244
                                        break;
 
5245
                                case OBJ_SEQFEAT:
 
5246
                                        AddToAnnot(&(bssp->annot), 1, newptr);
 
5247
                                        break;
 
5248
                                case OBJ_SEQALIGN:
 
5249
                                case OBJ_SEQHIST_ALIGN:
 
5250
                                        AddToAnnot(&(bssp->annot), 2, newptr);
 
5251
                                        break;
 
5252
                                case OBJ_SEQGRAPH:
 
5253
                                        AddToAnnot(&(bssp->annot), 3, newptr);
 
5254
                                        break;
 
5255
                                default:
 
5256
                                        no_good = TRUE;
 
5257
                                        break;
 
5258
                        }
 
5259
                        break;
 
5260
                case OBJ_BIOSEQ:
 
5261
                        bsp = (BioseqPtr)(ptr);
 
5262
                        switch (newtype)
 
5263
                        {
 
5264
                                case OBJ_BIOSEQSET:
 
5265
                                case OBJ_BIOSEQ:
 
5266
                                        if (omdp == NULL)
 
5267
                                        {
 
5268
                                                ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
 
5269
                                                return TRUE;
 
5270
                                        }
 
5271
                                        if (omdp->choice == NULL)
 
5272
                                        {
 
5273
                                                omdp->choice = ValNodeNew(NULL);
 
5274
                                                omdp->choicetype = OBJ_SEQENTRY;
 
5275
                                                omdp->choice->data.ptrvalue = newptr;
 
5276
                                                if (newtype == OBJ_BIOSEQ)
 
5277
                                                        omdp->choice->choice = 1;
 
5278
                                                else
 
5279
                                                        omdp->choice->choice = 2;
 
5280
                                        }
 
5281
                                        if ((gcp->parentitem != NULL) && (gcp->prevlink != NULL))
 
5282
                                        {
 
5283
                                                omdp->choice->next = *(gcp->prevlink);
 
5284
                                                *(gcp->prevlink) = omdp->choice;
 
5285
                                                ObjMgrConnectFunc(omp, newtype, newptr, gcp->parenttype, gcp->parentitem);
 
5286
                                        }
 
5287
                                        else
 
5288
                                                no_good = TRUE;
 
5289
                                        break;
 
5290
                                case OBJ_SEQDESC:
 
5291
                                        ValNodeLink(&(bsp->descr), (ValNodePtr)newptr);
 
5292
                                        break;
 
5293
                                case OBJ_PUB:                      /* make a pubdesc */
 
5294
                                case OBJ_SEQFEAT_CIT:
 
5295
                                        vnp = DescrFromPub((ValNodePtr)newptr);
 
5296
                                        ValNodeLink(&(bsp->descr), vnp);
 
5297
                                        break;
 
5298
                                case OBJ_SEQENTRY:
 
5299
                                        if ((gcp->parentitem != NULL) && (gcp->prevlink != NULL))
 
5300
                                        {
 
5301
                                                omdp->choice->next = *(gcp->prevlink);
 
5302
                                                *(gcp->prevlink) = omdp->choice;
 
5303
                                                ObjMgrConnectFunc(omp, newtype, newptr, gcp->parenttype, gcp->parentitem);
 
5304
                                        }
 
5305
                                        else
 
5306
                                                no_good = TRUE;
 
5307
                                        break;
 
5308
                                case OBJ_SEQANNOT:
 
5309
                                        AddAnAnnot(&(bsp->annot), newptr);
 
5310
                                        break;
 
5311
                                case OBJ_SEQFEAT:
 
5312
                                        AddToAnnot(&(bsp->annot), 1, newptr);
 
5313
                                        break;
 
5314
                                case OBJ_SEQALIGN:
 
5315
                                case OBJ_SEQHIST_ALIGN:
 
5316
                                        AddToAnnot(&(bsp->annot), 2, newptr);
 
5317
                                        break;
 
5318
                                case OBJ_SEQGRAPH:
 
5319
                                        AddToAnnot(&(bsp->annot), 3, newptr);
 
5320
                                        break;
 
5321
                                case OBJ_SEQHIST:
 
5322
                                        if (bsp->hist == NULL)
 
5323
                                        {
 
5324
                                                bsp->hist = (SeqHistPtr)newptr;
 
5325
                                                break;
 
5326
                                        }
 
5327
                                default:
 
5328
                                        no_good = TRUE;
 
5329
                                        break;
 
5330
                        }
 
5331
                        break;
 
5332
                case OBJ_SEQDESC:
 
5333
                        vnp = (ValNodePtr)newptr;
 
5334
                        switch (newtype)
 
5335
                        {
 
5336
                                case OBJ_PUB:
 
5337
                                        vnp = DescrFromPub(vnp);
 
5338
                                case OBJ_SEQDESC:
 
5339
                                        if (gcp->prevlink != NULL)
 
5340
                                        {
 
5341
                                                vnp->next = *(gcp->prevlink);
 
5342
                                                *(gcp->prevlink) = vnp;
 
5343
                                        }
 
5344
                                        else
 
5345
                                                no_good = TRUE;
 
5346
                                        break;
 
5347
                                default:
 
5348
                                        no_good = TRUE;
 
5349
                                        break;
 
5350
                        }
 
5351
                        break;
 
5352
                case OBJ_SEQFEAT_CIT:
 
5353
                case OBJ_PUB_SET:
 
5354
                        vnp = (ValNodePtr)newptr;
 
5355
                        switch (newtype)
 
5356
                        {
 
5357
                                case OBJ_SEQDESC:
 
5358
                                        vnp = PubFromDescr(vnp);
 
5359
                                        if (vnp == NULL)
 
5360
                                        {
 
5361
                                                no_good = TRUE;
 
5362
                                                break;
 
5363
                                        }
 
5364
                                case OBJ_PUB:
 
5365
                                        if (gcp->prevlink != NULL)
 
5366
                                        {
 
5367
                                                vnp->next = *(gcp->prevlink);
 
5368
                                                *(gcp->prevlink) = vnp;
 
5369
                                        }
 
5370
                                        else
 
5371
                                                no_good = TRUE;
 
5372
                                        break;
 
5373
                                default:
 
5374
                                        no_good = TRUE;
 
5375
                                        break;
 
5376
                        }
 
5377
                        break;
 
5378
                case OBJ_SEQANNOT:
 
5379
                        sap = (SeqAnnotPtr)ptr;
 
5380
                        switch (newtype)
 
5381
                        {
 
5382
                                case OBJ_SEQFEAT:
 
5383
                                        if (! AddToSeqAnnot(sap, 1, newptr))
 
5384
                                                no_good = TRUE;
 
5385
                                        break;
 
5386
                                case OBJ_SEQALIGN:
 
5387
                                case OBJ_SEQHIST_ALIGN:
 
5388
                                        if (! AddToSeqAnnot(sap, 2, newptr))
 
5389
                                                no_good = TRUE;
 
5390
                                        break;
 
5391
                                case OBJ_SEQGRAPH:
 
5392
                                        if (! AddToSeqAnnot(sap, 3, newptr))
 
5393
                                                no_good = TRUE;
 
5394
                                        break;
 
5395
                                case OBJ_SEQANNOT:
 
5396
                                        sap = (SeqAnnotPtr)newptr;
 
5397
                                        if (gcp->prevlink != NULL)
 
5398
                                        {
 
5399
                                                sap->next = *(gcp->prevlink);
 
5400
                                                *(gcp->prevlink) = sap;
 
5401
                                        }
 
5402
                                        else
 
5403
                                                no_good = TRUE;
 
5404
                                        break;
 
5405
                                default:
 
5406
                                        no_good = TRUE;
 
5407
                                        break;
 
5408
                        }
 
5409
                        break;
 
5410
                case OBJ_BIOSEQ_MAPFEAT:
 
5411
                case OBJ_SEQFEAT:
 
5412
                        sfp = (SeqFeatPtr)ptr;
 
5413
                        switch (newtype)
 
5414
                        {
 
5415
                                case OBJ_SEQDESC:
 
5416
                                        newptr = (Pointer)PubFromDescr((ValNodePtr)newptr);
 
5417
                                case OBJ_PUB:
 
5418
                                        if (sfp->cit == NULL)
 
5419
                                        {
 
5420
                                                sfp->cit = ValNodeNew(NULL);
 
5421
                                                sfp->cit->choice = 1;
 
5422
                                        }
 
5423
                                        ValNodeLink((ValNodePtr PNTR)&(sfp->cit->data.ptrvalue), (ValNodePtr)newptr);
 
5424
                                        break;
 
5425
                                case OBJ_SEQFEAT:
 
5426
                                        sfp = (SeqFeatPtr)newptr;
 
5427
                                        if (gcp->prevlink != NULL)
 
5428
                                        {
 
5429
                                                sfp->next = *(gcp->prevlink);
 
5430
                                                *(gcp->prevlink) = sfp;
 
5431
                                        }
 
5432
                                        else
 
5433
                                                no_good = TRUE;
 
5434
                                        break;
 
5435
                                case OBJ_SEQLOC:
 
5436
                                        SeqLocFree(sfp->location); /* make assumption */
 
5437
                                        sfp->location = (ValNodePtr)newptr;
 
5438
                                        break;
 
5439
                                default:
 
5440
                                        no_good = TRUE;
 
5441
                                        break;
 
5442
                        }
 
5443
                        break;
 
5444
                case OBJ_SEQALIGN:
 
5445
                case OBJ_SEQHIST_ALIGN:
 
5446
                case OBJ_SEQHIST:
 
5447
                        switch (newtype)
 
5448
                        {
 
5449
                                case OBJ_SEQALIGN:
 
5450
                                case OBJ_SEQHIST_ALIGN:
 
5451
                                        salp = (SeqAlignPtr)newptr;
 
5452
                                        if (gcp->prevlink != NULL)
 
5453
                                        {
 
5454
                                                salp->next = *(gcp->prevlink);
 
5455
                                                *(gcp->prevlink) = salp;
 
5456
                                        }
 
5457
                                        else
 
5458
                                                no_good = TRUE;
 
5459
                                        break;
 
5460
                                default:
 
5461
                                        no_good = TRUE;
 
5462
                                        break;
 
5463
                        }
 
5464
                        break;
 
5465
                case OBJ_SEQGRAPH:
 
5466
                        switch (newtype)
 
5467
                        {
 
5468
                                case OBJ_SEQGRAPH:
 
5469
                                        sgp = (SeqGraphPtr)newptr;
 
5470
                                        if (gcp->prevlink != NULL)
 
5471
                                        {
 
5472
                                                sgp->next = *(gcp->prevlink);
 
5473
                                                *(gcp->prevlink) = sgp;
 
5474
                                        }
 
5475
                                        else
 
5476
                                                no_good = TRUE;
 
5477
                                        break;
 
5478
                                default:
 
5479
                                        no_good = TRUE;
 
5480
                                        break;
 
5481
                        }
 
5482
                        break;
 
5483
                case OBJ_SEQLOC:
 
5484
                case OBJ_SEQID:
 
5485
                case OBJ_SEQENTRY:
 
5486
                default:
 
5487
                        no_good = TRUE;
 
5488
                        break;
 
5489
        }
 
5490
        
 
5491
        ObjMgrUnlock();
 
5492
 
 
5493
        if (no_good)
 
5494
        {
 
5495
                ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: [%d] into [%d]", (int)newtype, (int)into);
 
5496
        }
 
5497
        else
 
5498
        {
 
5499
                gdsp->succeeded = TRUE;
 
5500
                switch (newtype)
 
5501
                {
 
5502
                        case OBJ_BIOSEQ:
 
5503
                        case OBJ_BIOSEQSET:
 
5504
                                break;
 
5505
                        default:
 
5506
                                if (omdp != NULL)
 
5507
                                        ObjMgrDelete(omdp->datatype, omdp->dataptr);
 
5508
                }
 
5509
        }
 
5510
 
 
5511
        return TRUE;
 
5512
}
 
5513
 
 
5514
static Boolean CopyDataProc (GatherContextPtr gcp)
 
5515
{
 
5516
        OMProcControlPtr ompcp;
 
5517
        ObjMgrTypePtr omtp;
 
5518
        ObjMgrPtr omp;
 
5519
        Uint2 type;
 
5520
        Pointer ptr, ptr2;
 
5521
        Boolean was_choice = FALSE;
 
5522
        GDSPtr gdsp;
 
5523
 
 
5524
        gdsp = (GDSPtr)(gcp->userdata);
 
5525
        ompcp = gdsp->ompcp;
 
5526
 
 
5527
    ptr = gcp->thisitem;
 
5528
        type = gcp->thistype;
 
5529
    ompcp->input_data = ptr;
 
5530
    
 
5531
        switch (gcp->thistype)
 
5532
        {
 
5533
                case OBJ_BIOSEQSET:
 
5534
                case OBJ_BIOSEQ:
 
5535
                        if (gcp->sep != NULL)
 
5536
                        {
 
5537
                                ompcp->input_choice = gcp->sep;
 
5538
                                ptr = (Pointer)(gcp->sep);
 
5539
                                ompcp->input_choicetype = OBJ_SEQENTRY;
 
5540
                                type = OBJ_SEQENTRY;
 
5541
                                was_choice = TRUE;
 
5542
                        }
 
5543
                        break;
 
5544
                default:
 
5545
                        break;
 
5546
        }
 
5547
 
 
5548
        omp = ObjMgrReadLock();
 
5549
        omtp = ObjMgrTypeFind(omp, type, NULL, NULL);
 
5550
        ObjMgrUnlock();
 
5551
 
 
5552
        if (omtp == NULL)
 
5553
        {
 
5554
                ErrPostEx(SEV_ERROR,0,0,"CopyDataProc: can't find type [%d]", (int)type);
 
5555
                return TRUE;
 
5556
        }
 
5557
 
 
5558
        ptr2 = AsnIoMemCopy(ptr, omtp->asnread, omtp->asnwrite);
 
5559
        if (ptr2 != NULL)
 
5560
        {
 
5561
                gdsp->succeeded = TRUE;
 
5562
 
 
5563
                if (! was_choice)
 
5564
                {
 
5565
                        ompcp->output_data = ptr2;
 
5566
                        ompcp->output_itemtype = type;
 
5567
                }
 
5568
                else
 
5569
                {
 
5570
                        ompcp->output_choice = ptr2;
 
5571
                        ompcp->output_choicetype = type;
 
5572
                        ompcp->output_data = ((ValNodePtr)(ptr2))->data.ptrvalue;
 
5573
                        ompcp->output_itemtype = gcp->thistype;
 
5574
                }
 
5575
                switch (ompcp->output_itemtype)
 
5576
                {
 
5577
                        case OBJ_BIOSEQSET:    /* these types Add to the ObjMgr themselves */
 
5578
                        case OBJ_BIOSEQ:
 
5579
                        case OBJ_SEQSUB:
 
5580
                                break;
 
5581
                        default:
 
5582
                                ObjMgrAdd(ompcp->output_itemtype, ompcp->output_data);
 
5583
                                break;
 
5584
                }
 
5585
        }
 
5586
        return TRUE;
 
5587
}
 
5588
 
 
5589
static Boolean NEAR GenericGatherDataForProc (OMProcControlPtr ompcp, Boolean sel, Int2 func)
 
5590
{
 
5591
        ObjMgrDataPtr omdp;
 
5592
        SelStructPtr ssp;
 
5593
        Boolean retval = FALSE, data_changed = FALSE;
 
5594
        static CharPtr funcs [5] = {
 
5595
                "GatherDataForProc",
 
5596
                "DetachDataForProc",
 
5597
                "AttachDataForProc",
 
5598
                "CopyDataForProc",
 
5599
                "ReplaceDataForProc" };
 
5600
        GatherItemProc gip;
 
5601
        GDS gds;
 
5602
        ObjMgrPtr omp;
 
5603
 
 
5604
        gds.succeeded = retval;
 
5605
        gds.ompcp = ompcp;
 
5606
 
 
5607
        if (sel)
 
5608
        {
 
5609
                ssp = ObjMgrGetSelected();
 
5610
                if (ssp == NULL)
 
5611
                {
 
5612
                        /*
 
5613
                        ErrPostEx(SEV_ERROR,0,0,"%s: Nothing was selected", funcs[func]);
 
5614
                        */
 
5615
                        return retval;
 
5616
                }
 
5617
                ompcp->input_entityID = ssp->entityID;
 
5618
                ompcp->input_itemID = ssp->itemID;
 
5619
                ompcp->input_itemtype = ssp->itemtype;
 
5620
        }
 
5621
 
 
5622
        if (func == 1) /* detach: changes selection */
 
5623
                ObjMgrDeSelect(ompcp->input_entityID, ompcp->input_itemID, ompcp->input_itemtype, 0, NULL);
 
5624
 
 
5625
        omp = ObjMgrReadLock();
 
5626
        omdp = ObjMgrGetDataStruct (omp, ompcp->input_entityID);
 
5627
 
 
5628
        if (omdp == NULL)
 
5629
        {
 
5630
                ObjMgrUnlock();
 
5631
                ErrPostEx(SEV_ERROR,0,0,"%s: can't match entityID", funcs[func]);
 
5632
                return retval;
 
5633
        }
 
5634
        
 
5635
        if ((ompcp->input_itemID <= 1) &&
 
5636
            ((ompcp->input_itemtype == 0) || (ompcp->input_itemtype == omdp->datatype)))  /* top level */
 
5637
        {
 
5638
                ompcp->input_choice = omdp->choice;
 
5639
                ompcp->input_choicetype = omdp->choicetype;
 
5640
                ompcp->input_itemtype = omdp->datatype;
 
5641
                ompcp->input_data = omdp->dataptr;
 
5642
                ompcp->whole_entity = TRUE;
 
5643
                if ((func == 0) || (func == 1))  /* gather or detach */
 
5644
                {
 
5645
                        ObjMgrUnlock();
 
5646
                        return TRUE;
 
5647
                }
 
5648
        }
 
5649
 
 
5650
        ObjMgrUnlock();
 
5651
 
 
5652
        if (func == 4)    /* replace */
 
5653
        {
 
5654
                if (ompcp->input_itemtype != ompcp->output_itemtype)
 
5655
                {
 
5656
                        ErrPostEx(SEV_ERROR,0,0,"%s: input type %d != output type %d",
 
5657
                                funcs[func], (int)(ompcp->input_itemtype), (int)(ompcp->output_itemtype));
 
5658
                        return FALSE;
 
5659
                }
 
5660
 
 
5661
                if (ompcp->output_data == NULL)
 
5662
                {
 
5663
                        ErrPostEx(SEV_ERROR,0,0,"%s: no output_data", funcs[func]);
 
5664
                        return FALSE;
 
5665
                }
 
5666
        }
 
5667
 
 
5668
        switch(func)
 
5669
        {
 
5670
                case 0:
 
5671
                        gip = GatherDataProc;
 
5672
                        break;
 
5673
                case 1:
 
5674
                        gip = DetachDataProc;
 
5675
                        data_changed = TRUE;
 
5676
                        break;
 
5677
                case 2:
 
5678
                        gip = AttachDataProc;
 
5679
                        data_changed = TRUE;
 
5680
                        break;
 
5681
                case 3:
 
5682
                        gip = CopyDataProc;
 
5683
                        break;
 
5684
                case 4:
 
5685
                        gip = ReplaceDataProc;
 
5686
                        data_changed = TRUE;
 
5687
                        break;
 
5688
 
 
5689
        }
 
5690
 
 
5691
        retval = GatherItemFunc (ompcp->input_entityID, ompcp->input_itemID,
 
5692
                  ompcp->input_itemtype,(Pointer)(&gds), gip, NULL, ompcp->do_not_reload_from_cache);
 
5693
 
 
5694
        if (! retval)
 
5695
                ErrPostEx(SEV_ERROR,0,0,"%s: can't do the gather", funcs[func]);
 
5696
        else
 
5697
                retval = gds.succeeded;
 
5698
 
 
5699
        if ((retval) && (data_changed))   /* set the dirty flag */
 
5700
        {
 
5701
                ObjMgrSetDirtyFlag(ompcp->input_entityID, TRUE);
 
5702
        }
 
5703
        return retval;
 
5704
}
 
5705
 
 
5706
/****************************************************************************
 
5707
*
 
5708
*   GatherDataForProc(ompcp, sel)
 
5709
*
 
5710
*       fills in data, choice, and choictype in OMProcControlPtr
 
5711
*         sets ompcp->whole_entity TRUE if appropriate
 
5712
*       returns TRUE if it did it
 
5713
*       if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
 
5714
*          returns FALSE if nothing selected.. Does ErrPostEx() for it
 
5715
*
 
5716
****************************************************************************/
 
5717
NLM_EXTERN Boolean LIBCALL GatherDataForProc (OMProcControlPtr ompcp, Boolean sel)
 
5718
{
 
5719
        return GenericGatherDataForProc(ompcp, sel, 0);
 
5720
}
 
5721
 
 
5722
/****************************************************************************
 
5723
*
 
5724
*   DetachDataForProc(ompcp, sel)
 
5725
*
 
5726
*       fills in data, choice, and choictype in OMProcControlPtr
 
5727
*         sets ompcp->whole_entity TRUE if appropriate
 
5728
*       returns TRUE if it did it
 
5729
*       if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
 
5730
*          returns FALSE if nothing selected.. Does ErrPostEx() for it
 
5731
*       Detaches data item from surrounding data if necessary
 
5732
*
 
5733
****************************************************************************/
 
5734
NLM_EXTERN Boolean LIBCALL DetachDataForProc (OMProcControlPtr ompcp, Boolean sel)
 
5735
{
 
5736
        return GenericGatherDataForProc(ompcp, sel, 1);
 
5737
}
 
5738
 
 
5739
/****************************************************************************
 
5740
*
 
5741
*   AttachDataForProc(ompcp, sel)
 
5742
*
 
5743
*       fills in data, choice, and choictype in OMProcControlPtr
 
5744
*         sets ompcp->whole_entity TRUE if appropriate
 
5745
*       returns TRUE if it did it
 
5746
*       if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
 
5747
*          returns FALSE if nothing selected.. Does ErrPostEx() for it
 
5748
*       Attaches data in output section of ompcp into the input section
 
5749
*
 
5750
****************************************************************************/
 
5751
NLM_EXTERN Boolean LIBCALL AttachDataForProc (OMProcControlPtr ompcp, Boolean sel)
 
5752
{
 
5753
        return GenericGatherDataForProc(ompcp, sel, 2);
 
5754
}
 
5755
 
 
5756
/****************************************************************************
 
5757
*
 
5758
*   CopyDataForProc(ompcp, sel)
 
5759
*
 
5760
*       fills in data, choice, and choictype in OMProcControlPtr
 
5761
*         sets ompcp->whole_entity TRUE if appropriate
 
5762
*       returns TRUE if it did it
 
5763
*       if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
 
5764
*          returns FALSE if nothing selected.. Does ErrPostEx() for it
 
5765
*       Attaches copy of data in output section of ompcp
 
5766
*
 
5767
****************************************************************************/
 
5768
NLM_EXTERN Boolean LIBCALL CopyDataForProc (OMProcControlPtr ompcp, Boolean sel)
 
5769
{
 
5770
        return GenericGatherDataForProc(ompcp, sel, 3);
 
5771
}
 
5772
 
 
5773
/****************************************************************************
 
5774
*
 
5775
*   ReplaceDataForProc(ompcp, sel)
 
5776
*
 
5777
*       fills in data, choice, and choictype in OMProcControlPtr
 
5778
*         sets ompcp->whole_entity TRUE if appropriate
 
5779
*       returns TRUE if it did it
 
5780
*       if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
 
5781
*          returns FALSE if nothing selected.. Does ErrPostEx() for it
 
5782
*       Replaces data in input section of ompcp with the output section
 
5783
*       Data in input section is deleted
 
5784
*
 
5785
****************************************************************************/
 
5786
NLM_EXTERN Boolean LIBCALL ReplaceDataForProc (OMProcControlPtr ompcp, Boolean sel)
 
5787
{
 
5788
        return GenericGatherDataForProc(ompcp, sel, 4);
 
5789
}
 
5790
 
 
5791
/*****************************************************************************
 
5792
*
 
5793
*   GatherProcLaunch(proctype, sel, entityID, itemID, itemtype,
 
5794
*        inputtype, subinputtype, outputtype, suboutputtype)
 
5795
*       looks for ALL proctype in priority order that
 
5796
*               matches inputtype and outputtype
 
5797
*     if (sel) then fills in entityID,itemID,itemtype with currently selected
 
5798
*        item
 
5799
*     else
 
5800
*        uses the function arguments
 
5801
*     locates the data pointer, determines the subtype (if any)
 
5802
*     then finds the process that will return OM_MSG_RET_DONE in priority order
 
5803
*       0 on outputtype, inputsubtype, outputsubtype matches any
 
5804
*     if subtype can be matched on input/output, takes in preference over
 
5805
*        more general proc
 
5806
*
 
5807
*     USAGE:
 
5808
*     1) To launch an editor for the currently selected item
 
5809
*      GatherProcLaunch(OMPROC_EDIT,TRUE,0,0,0,0,0,0,0);
 
5810
*     2) To launch an editor to create a new seq_descr of type pub
 
5811
*      GatherProcLaunch(OMPROC_EDIT,FALSE,0,0,0,OBJ_SEQDESC,Seq_descr_pub,0,0);
 
5812
*     3) To launch an editor for a specific seq_descr
 
5813
*      GatherProcLaunch(OMPROC_EDIT,FALSE,2,1,4,0,0,0,0);
 
5814
*        (where the 3 numbers identify the seq_descr)
 
5815
*     4)To launch an editor which will create a new seq_descr and attach it
 
5816
*        to the currently selected Bioseq
 
5817
*      GatherProcLaunch(OMPROC_EDIT,TRUE,0,0,0,OBJ_SEQDESC,Seq_descr_pub,0,0)
 
5818
*        Note in this case ompcp->input_entityid, .input_itemid, input_itemtype
 
5819
*          well refer to a Bioseq. The editor should check the input_itemtype
 
5820
*          and decide if it can attach it's output to it, or if it is an
 
5821
*          input type mismatch error.
 
5822
*     5) To launch an editor which will create a new seq_descr and attach to
 
5823
*        a specific Bioseq
 
5824
*         (Same as (4) but sel=FALSE, and entitid,itemid,itemtype filled in
 
5825
*          for the Bioseq).
 
5826
*
 
5827
*     GENERAL RULES:
 
5828
*
 
5829
*     All this means the function will be called with OMProcControlPtr (ompcp)
 
5830
*      fields filled in (input_entityid, input_itemid, input_itemtype) as:
 
5831
*       1) Create new one, place in desktop = 0,0,0
 
5832
*       2) Edit old one, non-zero values, with input_itemtype matching the type
 
5833
*          of the editor.
 
5834
*       3) Create a new one, attach it to something else, non-zero values,
 
5835
*          with input_itemtype not matching the type of the editor.
 
5836
*
 
5837
*     Functions to install the returned values are for the cases above:
 
5838
*       1) ObjMgrRegister()
 
5839
*       2) GatherReplaceDataForProc()
 
5840
*       3) GatherAttachDataForProc()
 
5841
*
 
5842
*     returns the return from the proc, or OM_MSG_RET_NOPROC if not found
 
5843
*
 
5844
*****************************************************************************/
 
5845
NLM_EXTERN Int2 GatherProcLaunch (Uint2 proctype, Boolean sel, Uint2 entityID, Uint2 itemID,
 
5846
                    Uint2 itemtype, Uint2 inputtype, Uint2 subinputtype, Uint2 outputtype, Uint2 suboutputtype)
 
5847
{
 
5848
        ObjMgrPtr omp;
 
5849
        OMProcControl ompc;
 
5850
        ObjMgrProcPtr ompp=NULL;
 
5851
        ObjMgrTypePtr omtp;
 
5852
        Boolean retval, do_general_proc = FALSE;
 
5853
        Uint2 subtype = 0;
 
5854
        Int2 procval = OM_MSG_RET_NOPROC;
 
5855
 
 
5856
        MemSet((Pointer)(&ompc), 0, sizeof(OMProcControl));
 
5857
 
 
5858
        ompc.input_entityID = entityID;
 
5859
        ompc.input_itemID = itemID;
 
5860
        ompc.input_itemtype = itemtype;
 
5861
 
 
5862
        retval = GatherDataForProc(&ompc, sel);
 
5863
 
 
5864
        if (sel && (! retval))
 
5865
                return OM_MSG_RET_ERROR;
 
5866
 
 
5867
        if (entityID && (! retval))
 
5868
                return OM_MSG_RET_ERROR;
 
5869
 
 
5870
        if (! inputtype)   /* not set on input */
 
5871
                inputtype = ompc.input_itemtype;   /* could now be filled in */
 
5872
 
 
5873
        omp = NULL;  /* do all temporary read locks */
 
5874
        if ((! subinputtype) && (inputtype == ompc.input_itemtype)
 
5875
                               && (ompc.input_data != NULL))
 
5876
        {
 
5877
                omtp = ObjMgrTypeFind(omp, inputtype, NULL, NULL);
 
5878
                if (omtp != NULL)
 
5879
                        subinputtype = (*(omtp->subtypefunc))(ompc.input_data);
 
5880
        }
 
5881
 
 
5882
        while ((ompp = ObjMgrProcFindNext(omp, proctype, inputtype, outputtype, ompp)) != NULL)
 
5883
        {
 
5884
                if (ompp->subinputtype == subinputtype)
 
5885
                {
 
5886
                        ompc.proc = ompp;
 
5887
                        procval = (*(ompp->func))((Pointer)&ompc);
 
5888
                        switch (procval)
 
5889
                        {
 
5890
                                case OM_MSG_RET_ERROR:
 
5891
                                        ErrShow();
 
5892
                                        break;
 
5893
                                case OM_MSG_RET_DEL:
 
5894
                                        break;
 
5895
                                case OM_MSG_RET_OK:
 
5896
                                        break;
 
5897
                                case OM_MSG_RET_DONE:
 
5898
                                        goto all_done;
 
5899
                                default:
 
5900
                                        break;
 
5901
                        }
 
5902
                }
 
5903
                else if (! ompp->subinputtype)  /* general proc found */
 
5904
                        do_general_proc = TRUE;
 
5905
        }
 
5906
 
 
5907
        if (do_general_proc)    /* specific proc failed, try a general one */
 
5908
        {
 
5909
                while ((ompp = ObjMgrProcFindNext(omp, proctype, inputtype, outputtype, ompp)) != NULL)
 
5910
                {
 
5911
                        if (! ompp->subinputtype)
 
5912
                        {
 
5913
                                ompc.proc = ompp;
 
5914
                                procval = (*(ompp->func))((Pointer)&ompc);
 
5915
                                switch (procval)
 
5916
                                {
 
5917
                                        case OM_MSG_RET_ERROR:
 
5918
                                                ErrShow();
 
5919
                                                break;
 
5920
                                        case OM_MSG_RET_DEL:
 
5921
                                                break;
 
5922
                                        case OM_MSG_RET_OK:
 
5923
                                                break;
 
5924
                                        case OM_MSG_RET_DONE:
 
5925
                                                goto all_done;
 
5926
                                        default:
 
5927
                                                break;
 
5928
                                }
 
5929
                        }
 
5930
                }
 
5931
        }
 
5932
 
 
5933
all_done:
 
5934
        return procval;
 
5935
 
 
5936
}
 
5937
 
 
5938
NLM_EXTERN Int2 GatherSpecificProcLaunch (Uint2 procid, CharPtr procname, Uint2 proctype,
 
5939
                                          Boolean sel, Uint2 entityID, Uint2 itemID, Uint2 itemtype)
 
5940
{
 
5941
        ObjMgrPtr omp;
 
5942
        OMProcControl ompc;
 
5943
        ObjMgrProcPtr ompp=NULL;
 
5944
        Boolean retval;
 
5945
        Int2 procval = OM_MSG_RET_NOPROC;
 
5946
 
 
5947
        omp = ObjMgrGet ();
 
5948
 
 
5949
        MemSet((Pointer)(&ompc), 0, sizeof(OMProcControl));
 
5950
 
 
5951
        ompc.input_entityID = entityID;
 
5952
        ompc.input_itemID = itemID;
 
5953
        ompc.input_itemtype = itemtype;
 
5954
 
 
5955
        retval = GatherDataForProc(&ompc, sel);
 
5956
 
 
5957
        if (sel && (! retval))
 
5958
                return OM_MSG_RET_ERROR;
 
5959
 
 
5960
        if (entityID && (! retval))
 
5961
                return OM_MSG_RET_ERROR;
 
5962
 
 
5963
        ompp = ObjMgrProcFind (omp, procid, procname, proctype);
 
5964
        if (ompp == NULL)
 
5965
                return OM_MSG_RET_ERROR;
 
5966
 
 
5967
        ompc.proc = ompp;
 
5968
        procval = (*(ompp->func))((Pointer)&ompc);
 
5969
        switch (procval)
 
5970
        {
 
5971
                case OM_MSG_RET_ERROR:
 
5972
                        ErrShow();
 
5973
                        break;
 
5974
                case OM_MSG_RET_DEL:
 
5975
                        break;
 
5976
                case OM_MSG_RET_OK:
 
5977
                        break;
 
5978
                case OM_MSG_RET_DONE:
 
5979
                        goto all_done;
 
5980
                default:
 
5981
                        break;
 
5982
        }
 
5983
 
 
5984
all_done:
 
5985
        return procval;
 
5986
 
 
5987
}
 
5988
/*****************************************************************
 
5989
*
 
5990
*  GatherOverWrite (oldptr, newptr, type)
 
5991
*      type is OBJ_...
 
5992
*      overwrites oldptr with contents of newptr
 
5993
*      sets any "next" pointers contained in newptr to point to the same
 
5994
*        chain as those in oldptr did
 
5995
*      this function is used for making a varient copy of an object, then
 
5996
*        replacing it in another object without changing points to or from
 
5997
*        this object
 
5998
*******************************************************************/
 
5999
NLM_EXTERN Boolean LIBCALL GatherOverWrite (Pointer oldptr, Pointer newptr, Uint2 type)
 
6000
{
 
6001
    size_t size = 0;
 
6002
        Pointer dest, next=NULL, oldsrc;
 
6003
        ValNodePtr vnp;
 
6004
 
 
6005
        if ((oldptr == NULL) || (newptr == NULL))
 
6006
                return FALSE;
 
6007
 
 
6008
        oldsrc = oldptr;
 
6009
        switch (type)
 
6010
        {
 
6011
                case OBJ_SEQSUB:
 
6012
                        size = sizeof(SeqSubmit);
 
6013
                        break;
 
6014
                case OBJ_SUBMIT_BLOCK:
 
6015
                        size = sizeof(SubmitBlock);
 
6016
                        break;
 
6017
                case OBJ_SEQSUB_CONTACT:
 
6018
                        size = sizeof(ContactInfo);
 
6019
                        break;
 
6020
                case OBJ_SEQSUB_CIT:
 
6021
                        size = sizeof(CitSub);
 
6022
                        break;
 
6023
                case OBJ_SEQHIST:
 
6024
                        size = sizeof(SeqHist);
 
6025
                        break;
 
6026
                case OBJ_BIOSEQSET:
 
6027
                        size = sizeof(BioseqSet);
 
6028
                        break;
 
6029
                case OBJ_BIOSEQ:
 
6030
                        size = sizeof(Bioseq);
 
6031
                        break;
 
6032
                case OBJ_SEQDESC:
 
6033
                case OBJ_BIOSEQ_SEG:
 
6034
                case OBJ_PUB:
 
6035
                case OBJ_SEQFEAT_CIT:
 
6036
                case OBJ_PUB_SET:
 
6037
                case OBJ_SEQLOC:
 
6038
                case OBJ_SEQID:
 
6039
                case OBJ_SEQENTRY:
 
6040
                        vnp = (ValNodePtr)oldptr;
 
6041
                        oldsrc = &(vnp->data);
 
6042
                        size = sizeof(DataVal);
 
6043
                        vnp = (ValNodePtr)newptr;
 
6044
                        newptr = &(vnp->data);
 
6045
                        break;
 
6046
                case OBJ_BIOSEQ_MAPFEAT:
 
6047
                case OBJ_SEQFEAT:
 
6048
                        size = sizeof(SeqFeat);
 
6049
                        next = (Pointer)(((SeqFeatPtr)(oldptr))->next);
 
6050
                        (((SeqFeatPtr)(oldptr))->next) = NULL;
 
6051
                        (((SeqFeatPtr)(newptr))->next) = (SeqFeatPtr)next;
 
6052
                        break;
 
6053
                case OBJ_SEQANNOT:
 
6054
                        size = sizeof(SeqAnnot);
 
6055
                        next = (Pointer)(((SeqAnnotPtr)(oldptr))->next);
 
6056
                        (((SeqAnnotPtr)(oldptr))->next) = NULL;
 
6057
                        (((SeqAnnotPtr)(newptr))->next) = (SeqAnnotPtr)next;
 
6058
                        break;
 
6059
                case OBJ_SEQALIGN:
 
6060
                case OBJ_SEQHIST_ALIGN:
 
6061
                        size = sizeof(SeqAlign);
 
6062
                        next = (Pointer)(((SeqAlignPtr)(oldptr))->next);
 
6063
                        (((SeqAlignPtr)(oldptr))->next) = NULL;
 
6064
                        (((SeqAlignPtr)(newptr))->next) = (SeqAlignPtr)next;
 
6065
                        break;
 
6066
                case OBJ_SEQGRAPH:
 
6067
                        size = sizeof(SeqGraph);
 
6068
                        next = (Pointer)(((SeqGraphPtr)(oldptr))->next);
 
6069
                        (((SeqGraphPtr)(oldptr))->next) = NULL;
 
6070
                        (((SeqGraphPtr)(newptr))->next) = (SeqGraphPtr)next;
 
6071
                        break;
 
6072
                default:
 
6073
                        ErrPostEx(SEV_ERROR,0,0,"ObjMgrOverWrite: unsupported type %d",
 
6074
                                (int)(type));
 
6075
                        return FALSE;
 
6076
        }
 
6077
 
 
6078
        if (! size)
 
6079
                return FALSE;
 
6080
 
 
6081
        dest = MemNew(size);   /* temporary buffer for copies */
 
6082
        if (dest == NULL)
 
6083
        {
 
6084
                ErrPostEx(SEV_ERROR,0,0,"ObjMgrOverWrite: can't allocate buffer");
 
6085
                return FALSE;
 
6086
        }
 
6087
    
 
6088
        MemCopy(dest, oldsrc, size);    /* replace the contents */
 
6089
        MemCopy(oldsrc, newptr, size);
 
6090
        MemCopy(newptr, dest, size);
 
6091
 
 
6092
        MemFree(dest);
 
6093
 
 
6094
        return TRUE;
 
6095
}
 
6096
 
 
6097
 
 
6098
 
 
6099
/*****************************************************************************/
 
6100
 
 
6101
/* AssignIDsInEntity/VisitObjectsInEntity section */
 
6102
 
 
6103
typedef struct internalacc {
 
6104
  Uint2             entityID;
 
6105
  Int2              itemIDs [OBJ_MAX];
 
6106
  Boolean           assignIDs;
 
6107
  GatherObjectProc  callback;
 
6108
  Pointer           userdata;
 
6109
  BoolPtr           objMgrFilter;
 
6110
} InternalACC, PNTR InternalACCPtr;
 
6111
 
 
6112
static void AssignIDs (InternalACCPtr iap, GatherIndexPtr gip, Uint1 itemtype, Uint1 subtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6113
 
 
6114
{
 
6115
  if (iap == NULL || gip == NULL) return;
 
6116
 
 
6117
  if (iap->assignIDs) {
 
6118
    gip->entityID = iap->entityID;
 
6119
    gip->itemID = iap->itemIDs [itemtype];
 
6120
    gip->itemtype = itemtype;
 
6121
    gip->subtype = subtype;
 
6122
    /* gip->deleteme = 0; */
 
6123
    gip->parenttype = parenttype;
 
6124
    gip->parentptr = parent;
 
6125
    gip->prevlink = prevlink;
 
6126
  }
 
6127
}
 
6128
 
 
6129
static Boolean VisitCallback (InternalACCPtr iap, Pointer dataptr, Uint1 itemtype, Uint1 subtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6130
 
 
6131
{
 
6132
  GatherObject  go;
 
6133
 
 
6134
  if (dataptr == NULL || iap == NULL || itemtype >= OBJ_MAX) return TRUE;
 
6135
 
 
6136
  if (iap->callback != NULL) {
 
6137
    if (iap->objMgrFilter == NULL || iap->objMgrFilter [itemtype]) {
 
6138
      go.entityID = iap->entityID;
 
6139
      go.itemID = iap->itemIDs [itemtype];
 
6140
      go.itemtype = itemtype;
 
6141
      go.subtype = subtype;
 
6142
      go.parenttype = parenttype;
 
6143
      go.dataptr = dataptr;
 
6144
      go.parentptr = parent;
 
6145
      go.prevlink = prevlink;
 
6146
      go.userdata = iap->userdata;
 
6147
      if (! iap->callback (&go)) return FALSE;
 
6148
    }
 
6149
  }
 
6150
 
 
6151
  return TRUE;
 
6152
}
 
6153
 
 
6154
static Boolean VisitSeqEntry (InternalACCPtr iap, SeqEntryPtr sep, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink);
 
6155
 
 
6156
static Boolean VisitPub (InternalACCPtr iap, ValNodePtr pub, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6157
 
 
6158
{
 
6159
  if (iap == NULL || pub == NULL) return TRUE;
 
6160
  (iap->itemIDs [itemtype])++;
 
6161
 
 
6162
  if (iap->callback != NULL) {
 
6163
    if (! VisitCallback (iap, (Pointer) pub, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6164
  }
 
6165
 
 
6166
  return TRUE;
 
6167
}
 
6168
 
 
6169
static Boolean VisitPubSet (InternalACCPtr iap, ValNodePtr vnp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6170
 
 
6171
{
 
6172
  Uint1       itemtype = OBJ_PUB_SET;
 
6173
  ValNodePtr  pub;
 
6174
 
 
6175
  if (iap == NULL || vnp == NULL) return TRUE;
 
6176
  (iap->itemIDs [itemtype])++;
 
6177
 
 
6178
  if (iap->callback != NULL) {
 
6179
    if (! VisitCallback (iap, (Pointer) vnp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6180
  }
 
6181
 
 
6182
  prevlink = (Pointer PNTR) &(vnp->data.ptrvalue);
 
6183
  for (pub = (ValNodePtr) vnp->data.ptrvalue; pub != NULL; pub = pub->next) {
 
6184
    if (! VisitPub (iap, pub, OBJ_SEQFEAT_CIT, (Pointer) vnp, itemtype, prevlink)) return FALSE;
 
6185
    prevlink = (Pointer PNTR) &(pub->next);
 
6186
  }
 
6187
 
 
6188
  return TRUE;
 
6189
}
 
6190
 
 
6191
static Boolean VisitSeqFeat (InternalACCPtr iap, SeqFeatPtr sfp, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6192
 
 
6193
{
 
6194
  if (iap == NULL || sfp == NULL) return TRUE;
 
6195
 
 
6196
  if ((! iap->assignIDs) && iap->callback != NULL) {
 
6197
    if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
 
6198
      return TRUE;
 
6199
    }
 
6200
  }
 
6201
 
 
6202
  while (sfp != NULL) {
 
6203
    (iap->itemIDs [itemtype])++;
 
6204
 
 
6205
    if (iap->assignIDs) {
 
6206
      AssignIDs (iap, &(sfp->idx), itemtype, FindFeatDefType (sfp), parent, parenttype, prevlink);
 
6207
    }
 
6208
 
 
6209
    if (iap->callback != NULL) {
 
6210
      if (! VisitCallback (iap, (Pointer) sfp, itemtype, sfp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6211
    }
 
6212
 
 
6213
    if (sfp->cit != NULL) {
 
6214
      if (! VisitPubSet (iap, sfp->cit, (Pointer) sfp, itemtype, (Pointer PNTR) &(sfp->cit))) return FALSE;
 
6215
    }
 
6216
 
 
6217
    prevlink = (Pointer PNTR) &(sfp->next);
 
6218
    sfp = sfp->next;
 
6219
  }
 
6220
 
 
6221
  return TRUE;
 
6222
}
 
6223
 
 
6224
static Uint2 nextAlignID = 0;
 
6225
 
 
6226
static Boolean VisitSeqAlign (InternalACCPtr iap, SeqAlignPtr sap, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6227
 
 
6228
{
 
6229
  if (iap == NULL || sap == NULL) return TRUE;
 
6230
 
 
6231
  if ((! iap->assignIDs) && iap->callback != NULL) {
 
6232
    if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
 
6233
      return TRUE;
 
6234
    }
 
6235
  }
 
6236
 
 
6237
  while (sap != NULL) {
 
6238
    (iap->itemIDs [itemtype])++;
 
6239
 
 
6240
    if (iap->assignIDs) {
 
6241
      AssignIDs (iap, &(sap->idx), itemtype, sap->type, parent, parenttype, prevlink);
 
6242
      if (sap->alignID == 0) {
 
6243
        nextAlignID++;
 
6244
        sap->alignID = nextAlignID;
 
6245
      }
 
6246
    }
 
6247
 
 
6248
    if (iap->callback != NULL) {
 
6249
      if (! VisitCallback (iap, (Pointer) sap, itemtype, sap->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6250
    }
 
6251
 
 
6252
    if (sap->segtype == SAS_DISC) {
 
6253
      if (! VisitSeqAlign (iap, (SeqAlignPtr) sap->segs, OBJ_SEQALIGN, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->segs))) return FALSE;
 
6254
    }
 
6255
 
 
6256
    prevlink = (Pointer PNTR) &(sap->next);
 
6257
    sap = sap->next;
 
6258
  }
 
6259
 
 
6260
  return TRUE;
 
6261
}
 
6262
 
 
6263
static Boolean VisitSeqGraph (InternalACCPtr iap, SeqGraphPtr sgp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6264
 
 
6265
{
 
6266
  Uint1  itemtype = OBJ_SEQGRAPH;
 
6267
 
 
6268
  if (iap == NULL || sgp == NULL) return TRUE;
 
6269
 
 
6270
  if ((! iap->assignIDs) && iap->callback != NULL) {
 
6271
    if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
 
6272
      return TRUE;
 
6273
    }
 
6274
  }
 
6275
 
 
6276
  while (sgp != NULL) {
 
6277
    (iap->itemIDs [itemtype])++;
 
6278
 
 
6279
    if (iap->assignIDs) {
 
6280
      AssignIDs (iap, &(sgp->idx), itemtype, 0, parent, parenttype, prevlink);
 
6281
    }
 
6282
 
 
6283
    if (iap->callback != NULL) {
 
6284
      if (! VisitCallback (iap, (Pointer) sgp, itemtype, sgp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6285
    }
 
6286
 
 
6287
    prevlink = (Pointer PNTR) &(sgp->next);
 
6288
    sgp = sgp->next;
 
6289
  }
 
6290
 
 
6291
  return TRUE;
 
6292
}
 
6293
 
 
6294
static Boolean VisitSeqAnnot (InternalACCPtr iap, SeqAnnotPtr sap, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6295
 
 
6296
{
 
6297
  Uint1  itemtype = OBJ_SEQANNOT;
 
6298
 
 
6299
  if (iap == NULL || sap == NULL) return TRUE;
 
6300
 
 
6301
  while (sap != NULL) {
 
6302
    (iap->itemIDs [itemtype])++;
 
6303
 
 
6304
    if (iap->assignIDs) {
 
6305
      AssignIDs (iap, &(sap->idx), itemtype, sap->type, parent, parenttype, prevlink);
 
6306
    }
 
6307
 
 
6308
    if (iap->callback != NULL) {
 
6309
      if (! VisitCallback (iap, (Pointer) sap, itemtype, sap->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6310
    }
 
6311
 
 
6312
    switch (sap->type) {
 
6313
      case 1 : /* feature table */
 
6314
        if (! VisitSeqFeat (iap, (SeqFeatPtr) sap->data, OBJ_SEQFEAT, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
 
6315
        break;
 
6316
      case 2 : /* alignments */
 
6317
        if (! VisitSeqAlign (iap, (SeqAlignPtr) sap->data, OBJ_SEQALIGN, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
 
6318
        break;
 
6319
      case 3 : /* graphs */
 
6320
        if (! VisitSeqGraph (iap, (SeqGraphPtr) sap->data, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
 
6321
        break;
 
6322
      default :
 
6323
        break;
 
6324
    }
 
6325
 
 
6326
    prevlink = (Pointer PNTR) &(sap->next);
 
6327
    sap = sap->next;
 
6328
  }
 
6329
 
 
6330
  return TRUE;
 
6331
}
 
6332
 
 
6333
static Boolean VisitSeqDescr (InternalACCPtr iap, SeqDescrPtr sdp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6334
 
 
6335
{
 
6336
  Uint1          itemtype = OBJ_SEQDESC;
 
6337
  ObjValNodePtr  ovp;
 
6338
 
 
6339
  if (iap == NULL || sdp == NULL) return TRUE;
 
6340
 
 
6341
  if ((! iap->assignIDs) && iap->callback != NULL) {
 
6342
    if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
 
6343
      return TRUE;
 
6344
    }
 
6345
  }
 
6346
 
 
6347
  while (sdp != NULL) {
 
6348
    (iap->itemIDs [itemtype])++;
 
6349
 
 
6350
    if (iap->assignIDs) {
 
6351
      if (sdp->extended != 0) {
 
6352
        ovp = (ObjValNodePtr) sdp;
 
6353
        AssignIDs (iap, &(ovp->idx), itemtype, sdp->choice, parent, parenttype, prevlink);
 
6354
      } else {
 
6355
        ErrPostEx (SEV_ERROR, 0, 0, "Descriptor item %d is not an ObjValNode",
 
6356
                   (int) iap->itemIDs [itemtype]);
 
6357
      }
 
6358
    }
 
6359
 
 
6360
    if (iap->callback != NULL) {
 
6361
      if (sdp->extended != 0) {
 
6362
        ovp = (ObjValNodePtr) sdp;
 
6363
        if (! VisitCallback (iap, (Pointer) sdp, itemtype, ovp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6364
      }
 
6365
    }
 
6366
 
 
6367
    prevlink = (Pointer PNTR) &(sdp->next);
 
6368
    sdp = sdp->next;
 
6369
  }
 
6370
 
 
6371
  return TRUE;
 
6372
}
 
6373
 
 
6374
static Boolean VisitSeqHist (InternalACCPtr iap, SeqHistPtr shp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6375
 
 
6376
{
 
6377
  Uint1  itemtype = OBJ_SEQHIST;
 
6378
 
 
6379
  if (iap == NULL || shp == NULL) return TRUE;
 
6380
  (iap->itemIDs [itemtype])++;
 
6381
 
 
6382
  if (iap->callback != NULL) {
 
6383
    if (! VisitCallback (iap, (Pointer) shp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6384
  }
 
6385
 
 
6386
  VisitSeqAlign (iap, shp->assembly, OBJ_SEQHIST_ALIGN, (Pointer) shp, itemtype, (Pointer PNTR) &(shp->assembly));
 
6387
 
 
6388
  return TRUE;
 
6389
}
 
6390
 
 
6391
static Boolean VisitSeqIds (InternalACCPtr iap, SeqIdPtr sip, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6392
 
 
6393
{
 
6394
  Uint1  itemtype = OBJ_SEQID;
 
6395
 
 
6396
  if (iap == NULL || sip == NULL) return TRUE;
 
6397
 
 
6398
  while (sip != NULL) {
 
6399
    (iap->itemIDs [itemtype])++;
 
6400
 
 
6401
    if (iap->callback != NULL) {
 
6402
      if (! VisitCallback (iap, (Pointer) sip, itemtype, sip->choice, parent, parenttype, prevlink)) return FALSE;
 
6403
    }
 
6404
 
 
6405
    prevlink = (Pointer PNTR) &(sip->next);
 
6406
    sip = sip->next;
 
6407
  }
 
6408
 
 
6409
  return TRUE;
 
6410
}
 
6411
 
 
6412
static Boolean VisitDelta (InternalACCPtr iap, DeltaSeqPtr dsp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6413
 
 
6414
{
 
6415
  Uint1  itemtype = OBJ_BIOSEQ_DELTA;
 
6416
 
 
6417
  if (iap == NULL || dsp == NULL) return TRUE;
 
6418
 
 
6419
  while (dsp != NULL) {
 
6420
    (iap->itemIDs [itemtype])++;
 
6421
 
 
6422
    if (iap->callback != NULL) {
 
6423
      if (! VisitCallback (iap, (Pointer) dsp, itemtype, dsp->choice, parent, parenttype, prevlink)) return FALSE;
 
6424
    }
 
6425
 
 
6426
    prevlink = (Pointer PNTR) &(dsp->next);
 
6427
    dsp = dsp->next;
 
6428
  }
 
6429
 
 
6430
  return TRUE;
 
6431
}
 
6432
 
 
6433
static Boolean VisitSegment (InternalACCPtr iap, SeqLocPtr head, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6434
 
 
6435
{
 
6436
  Uint1      itemtype = OBJ_BIOSEQ_SEG;
 
6437
  SeqLocPtr  slp;
 
6438
 
 
6439
  if (iap == NULL || head == NULL) return TRUE;
 
6440
 
 
6441
  slp = NULL;
 
6442
  while ((slp = SeqLocFindNext (head, slp)) != NULL) {
 
6443
    (iap->itemIDs [itemtype])++;
 
6444
 
 
6445
    if (iap->callback != NULL) {
 
6446
      if (! VisitCallback (iap, (Pointer) slp, itemtype, slp->choice, parent, parenttype, prevlink)) return FALSE;
 
6447
    }
 
6448
    prevlink = (Pointer PNTR) &(slp->next);
 
6449
  }
 
6450
 
 
6451
  return TRUE;
 
6452
}
 
6453
 
 
6454
static Boolean VisitBioseq (InternalACCPtr iap, BioseqPtr bsp, SeqEntryPtr curr, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6455
 
 
6456
{
 
6457
  SeqLocPtr  head;
 
6458
  Uint1      itemtype = OBJ_BIOSEQ;
 
6459
  ValNode    vn;
 
6460
 
 
6461
  if (iap == NULL || bsp == NULL) return TRUE;
 
6462
  (iap->itemIDs [itemtype])++;
 
6463
 
 
6464
  if (iap->assignIDs) {
 
6465
    AssignIDs (iap, &(bsp->idx), itemtype, bsp->repr, parent, parenttype, prevlink);
 
6466
    bsp->seqentry = curr;
 
6467
  }
 
6468
 
 
6469
  if (iap->callback != NULL) {
 
6470
    if (! VisitCallback (iap, (Pointer) bsp, itemtype, bsp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6471
  }
 
6472
 
 
6473
  switch (bsp->repr) {
 
6474
    case Seq_repr_map :
 
6475
      if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_MAPFEAT]) {
 
6476
        if (! VisitSeqFeat (iap, (SeqFeatPtr) bsp->seq_ext, OBJ_BIOSEQ_MAPFEAT, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
 
6477
      }
 
6478
      break;
 
6479
    case Seq_repr_seg :
 
6480
      if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_SEG]) {
 
6481
        vn.choice = SEQLOC_MIX;
 
6482
        vn.extended = 0;
 
6483
        vn.data.ptrvalue = bsp->seq_ext;
 
6484
        vn.next = NULL;
 
6485
        head = &vn;
 
6486
        if (! VisitSegment (iap, head, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
 
6487
      }
 
6488
      break;
 
6489
    case Seq_repr_ref :
 
6490
      if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_SEG]) {
 
6491
        head = (SeqLocPtr) bsp->seq_ext;
 
6492
        if (! VisitSegment (iap, head, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
 
6493
      }
 
6494
      break;
 
6495
    case Seq_repr_delta :
 
6496
      if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_DELTA]) {
 
6497
        if (! VisitDelta (iap, (DeltaSeqPtr) bsp->seq_ext, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
 
6498
      }
 
6499
      break;
 
6500
    default :
 
6501
      break;
 
6502
  }
 
6503
 
 
6504
  if (! VisitSeqHist (iap, bsp->hist, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->hist))) return FALSE;
 
6505
 
 
6506
  if (! VisitSeqDescr (iap, bsp->descr, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->descr))) return FALSE;
 
6507
 
 
6508
  if (! VisitSeqAnnot (iap, bsp->annot, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->annot))) return FALSE;
 
6509
 
 
6510
  return TRUE;
 
6511
}
 
6512
 
 
6513
static Boolean VisitBioseqSet (InternalACCPtr iap, BioseqSetPtr bssp, SeqEntryPtr curr, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6514
 
 
6515
{
 
6516
  Uint1        itemtype = OBJ_BIOSEQSET;
 
6517
  SeqEntryPtr  sep;
 
6518
 
 
6519
  if (iap == NULL || bssp == NULL) return TRUE;
 
6520
  (iap->itemIDs [itemtype])++;
 
6521
 
 
6522
  if (iap->assignIDs) {
 
6523
    AssignIDs (iap, &(bssp->idx), itemtype, bssp->_class, parent, parenttype, prevlink);
 
6524
    bssp->seqentry = curr;
 
6525
  }
 
6526
 
 
6527
  if (iap->callback != NULL) {
 
6528
    if (! VisitCallback (iap, (Pointer) bssp, itemtype, bssp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
 
6529
  }
 
6530
 
 
6531
  if (! VisitSeqDescr (iap, bssp->descr, (Pointer) bssp, itemtype, (Pointer PNTR) &(bssp->descr))) return FALSE;
 
6532
 
 
6533
  if (! VisitSeqAnnot (iap, bssp->annot, (Pointer) bssp, itemtype, (Pointer PNTR) &(bssp->annot))) return FALSE;
 
6534
 
 
6535
  prevlink = (Pointer PNTR) &(bssp->seq_set);
 
6536
  for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
 
6537
    if (! VisitSeqEntry (iap, sep, (Pointer) bssp, itemtype, prevlink)) return FALSE;
 
6538
    prevlink = (Pointer PNTR) &(sep->next);
 
6539
  }
 
6540
 
 
6541
  return TRUE;
 
6542
}
 
6543
 
 
6544
static Boolean VisitSeqEntry (InternalACCPtr iap, SeqEntryPtr sep, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6545
 
 
6546
{
 
6547
  if (iap == NULL || sep == NULL) return TRUE;
 
6548
 
 
6549
  if (IS_Bioseq (sep)) {
 
6550
    if (! VisitBioseq (iap, (BioseqPtr) sep->data.ptrvalue, sep, parent, parenttype, prevlink)) return FALSE;
 
6551
  } else if (IS_Bioseq_set (sep)) {
 
6552
    if (! VisitBioseqSet (iap, (BioseqSetPtr) sep->data.ptrvalue, sep, parent, parenttype, prevlink)) return FALSE;
 
6553
  }
 
6554
 
 
6555
  return TRUE;
 
6556
}
 
6557
 
 
6558
static Boolean VisitSeqSubCit (InternalACCPtr iap, CitSubPtr csp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6559
 
 
6560
{
 
6561
  Uint1  itemtype = OBJ_SEQSUB_CIT;
 
6562
 
 
6563
  if (iap == NULL || csp == NULL) return TRUE;
 
6564
  (iap->itemIDs [itemtype])++;
 
6565
 
 
6566
  if (iap->callback != NULL) {
 
6567
    if (! VisitCallback (iap, (Pointer) csp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6568
  }
 
6569
 
 
6570
  return TRUE;
 
6571
}
 
6572
 
 
6573
static Boolean VisitSeqSubContact (InternalACCPtr iap, ContactInfoPtr cip, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6574
 
 
6575
{
 
6576
  Uint1  itemtype = OBJ_SEQSUB_CONTACT;
 
6577
 
 
6578
 
 
6579
  if (iap == NULL || cip == NULL) return TRUE;
 
6580
  (iap->itemIDs [itemtype])++;
 
6581
 
 
6582
  if (iap->callback != NULL) {
 
6583
    if (! VisitCallback (iap, (Pointer) cip, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6584
  }
 
6585
 
 
6586
  return TRUE;
 
6587
}
 
6588
 
 
6589
static Boolean VisitSubBlock (InternalACCPtr iap, SubmitBlockPtr sbp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
 
6590
 
 
6591
{
 
6592
  Uint1  itemtype = OBJ_SUBMIT_BLOCK;
 
6593
 
 
6594
  if (iap == NULL || sbp == NULL) return TRUE;
 
6595
  (iap->itemIDs [itemtype])++;
 
6596
 
 
6597
  if (iap->callback != NULL) {
 
6598
    if (! VisitCallback (iap, (Pointer) sbp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
 
6599
  }
 
6600
 
 
6601
  if (! VisitSeqSubContact (iap, sbp->contact, (Pointer) sbp, itemtype, (Pointer PNTR) &(sbp->contact))) return FALSE;
 
6602
 
 
6603
  if (! VisitSeqSubCit (iap, sbp->cit, (Pointer) sbp, itemtype, (Pointer PNTR) &(sbp->cit))) return FALSE;
 
6604
 
 
6605
  return TRUE;
 
6606
}
 
6607
 
 
6608
static Boolean VisitSeqSubmit (InternalACCPtr iap, SeqSubmitPtr ssp)
 
6609
 
 
6610
{
 
6611
  Uint1         itemtype = OBJ_SEQSUB;
 
6612
  Pointer PNTR  prevlink;
 
6613
  SeqEntryPtr   sep;
 
6614
 
 
6615
  if (iap == NULL || ssp == NULL) return TRUE;
 
6616
  (iap->itemIDs [itemtype])++;
 
6617
 
 
6618
  if (iap->assignIDs) {
 
6619
    AssignIDs (iap, &(ssp->idx), itemtype, 0, NULL, 0, NULL);
 
6620
  }
 
6621
 
 
6622
  if (iap->callback != NULL) {
 
6623
    if (! VisitCallback (iap, (Pointer) ssp, itemtype, 0, NULL, 0, NULL)) return FALSE;
 
6624
  }
 
6625
 
 
6626
  if (! VisitSubBlock (iap, ssp->sub, (Pointer) ssp, itemtype, (Pointer PNTR) &(ssp->sub))) return FALSE;
 
6627
 
 
6628
  prevlink = (Pointer PNTR) &(ssp->data);
 
6629
  switch (ssp->datatype) {
 
6630
    case 1 : /* Seq-entrys */
 
6631
      for (sep = (SeqEntryPtr) ssp->data; sep != NULL; sep = sep->next) {
 
6632
        if (! VisitSeqEntry (iap, sep, (Pointer) ssp, itemtype, prevlink)) return FALSE;
 
6633
        prevlink = (Pointer PNTR) &(sep->next);
 
6634
      }
 
6635
      break;
 
6636
    case 2 : /* Seq-annots */
 
6637
      if (! VisitSeqAnnot (iap, (SeqAnnotPtr) ssp->data, (Pointer) ssp, itemtype, prevlink)) return FALSE;
 
6638
      break;
 
6639
    case 3 : /* SeqIds */
 
6640
      if (! VisitSeqIds (iap, (SeqIdPtr) ssp->data, (Pointer) ssp, itemtype, prevlink)) return FALSE;
 
6641
      break;
 
6642
    default :
 
6643
      break;
 
6644
  }
 
6645
 
 
6646
  return TRUE;
 
6647
}
 
6648
 
 
6649
/*****************************************************************************
 
6650
*
 
6651
*   AssignIDsInEntity (entityID, datatype, dataptr)
 
6652
*       Assigns entityID/itemID/itemtype, parent pointer, and prevlink to several
 
6653
*       data objects.  If entityID is > 0 it looks up the registered datatype and
 
6654
*       dataptr from the object manager.  Otherwise it uses the remaining parameters,
 
6655
*       assigning entityID 0 to the unregistered components.
 
6656
*
 
6657
*   GatherObjectsInEntity (entityID, datatype, dataptr, callback, userdata, objMgrFilter)
 
6658
*       Calls callback for objects within entity.  If the objMgrFilter parameter is NULL,
 
6659
*       every object type is visited, otherwise the array length should be OBJ_MAX, and
 
6660
*       the elements are from the OBJ_ list.
 
6661
*
 
6662
*****************************************************************************/
 
6663
 
 
6664
static Boolean VisitEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr,
 
6665
                            Boolean assignIDs, GatherObjectProc callback,
 
6666
                            Pointer userdata, BoolPtr objMgrFilter)
 
6667
 
 
6668
{
 
6669
  InternalACC    iac;
 
6670
  ObjMgrDataPtr  omdp;
 
6671
  ObjMgrPtr      omp;
 
6672
 
 
6673
  MemSet ((Pointer) &iac, 0, sizeof (InternalACC));
 
6674
  iac.entityID = entityID;
 
6675
  iac.assignIDs = assignIDs;
 
6676
  iac.callback = callback;
 
6677
  iac.userdata = userdata;
 
6678
  iac.objMgrFilter = objMgrFilter;
 
6679
 
 
6680
  if (entityID > 0) {
 
6681
    omp = ObjMgrReadLock ();
 
6682
    omdp = ObjMgrGetDataStruct (omp, entityID);
 
6683
    ObjMgrUnlock();
 
6684
    if (omdp == NULL) return FALSE;
 
6685
    if (omdp->choicetype == OBJ_SEQENTRY) {
 
6686
      datatype = omdp->choicetype;
 
6687
      dataptr = omdp->choice;
 
6688
    } else {
 
6689
      datatype = omdp->datatype;
 
6690
      dataptr = omdp->dataptr;
 
6691
    }
 
6692
  }
 
6693
 
 
6694
  if (datatype == 0 || dataptr == NULL) return FALSE;
 
6695
 
 
6696
  switch (datatype) {
 
6697
    case OBJ_SEQENTRY :
 
6698
      VisitSeqEntry (&iac, (SeqEntryPtr) dataptr, NULL, 0, NULL);
 
6699
      break;
 
6700
    case OBJ_BIOSEQ :
 
6701
      VisitBioseq (&iac, (BioseqPtr) dataptr, NULL, NULL, 0, NULL);
 
6702
      break;
 
6703
    case OBJ_BIOSEQSET :
 
6704
      VisitBioseqSet (&iac, (BioseqSetPtr) dataptr, NULL, NULL, 0, NULL);
 
6705
      break;
 
6706
    case OBJ_SEQDESC :
 
6707
      VisitSeqDescr (&iac, (SeqDescrPtr) dataptr, NULL, 0, NULL);
 
6708
      break;
 
6709
    case OBJ_SEQANNOT :
 
6710
      VisitSeqAnnot (&iac, (SeqAnnotPtr) dataptr, NULL, 0, NULL);
 
6711
      break;
 
6712
    case OBJ_SEQFEAT :
 
6713
      VisitSeqFeat (&iac, (SeqFeatPtr) dataptr, OBJ_SEQFEAT, NULL, 0, NULL);
 
6714
      break;
 
6715
    case OBJ_SEQALIGN :
 
6716
      VisitSeqAlign (&iac, (SeqAlignPtr) dataptr, OBJ_SEQALIGN, NULL, 0, NULL);
 
6717
      break;
 
6718
    case OBJ_SEQGRAPH :
 
6719
      VisitSeqGraph (&iac, (SeqGraphPtr) dataptr, NULL, 0, NULL);
 
6720
      break;
 
6721
    case OBJ_SEQSUB :
 
6722
      VisitSeqSubmit (&iac, (SeqSubmitPtr) dataptr);
 
6723
      break;
 
6724
    case OBJ_SUBMIT_BLOCK :
 
6725
      VisitSubBlock (&iac, (SubmitBlockPtr) dataptr, NULL, 0, NULL);
 
6726
      break;
 
6727
    case OBJ_SEQSUB_CONTACT :
 
6728
      VisitSeqSubContact (&iac, (ContactInfoPtr) dataptr, NULL, 0, NULL);
 
6729
      break;
 
6730
    case OBJ_SEQHIST :
 
6731
      VisitSeqHist (&iac, (SeqHistPtr) dataptr, NULL, 0, NULL);
 
6732
      break;
 
6733
    case OBJ_SEQHIST_ALIGN :
 
6734
      VisitSeqAlign (&iac, (SeqAlignPtr) dataptr, OBJ_SEQHIST_ALIGN, NULL, 0, NULL);
 
6735
      break;
 
6736
    case OBJ_PUB :
 
6737
      VisitPub (&iac, (ValNodePtr) dataptr, OBJ_PUB, NULL, 0, NULL);
 
6738
      break;
 
6739
    case OBJ_SEQSUB_CIT :
 
6740
      VisitSeqSubCit (&iac, (CitSubPtr) dataptr, NULL, 0, NULL);
 
6741
      break;
 
6742
    case OBJ_SEQID :
 
6743
      VisitSeqIds (&iac, (SeqIdPtr) dataptr, NULL, 0, NULL);
 
6744
      break;
 
6745
    default :
 
6746
      return FALSE;
 
6747
  }
 
6748
 
 
6749
  return TRUE;
 
6750
}
 
6751
 
 
6752
NLM_EXTERN Boolean LIBCALL AssignIDsInEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr)
 
6753
 
 
6754
{
 
6755
  return VisitEntity (entityID, datatype, dataptr, TRUE, NULL, NULL, NULL);
 
6756
}
 
6757
 
 
6758
NLM_EXTERN Boolean LIBCALL GatherObjectsInEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr,
 
6759
                                                  GatherObjectProc callback, Pointer userdata, BoolPtr objMgrFilter)
 
6760
 
 
6761
{
 
6762
  if (callback == NULL) return FALSE;
 
6763
  return VisitEntity (entityID, datatype, dataptr, FALSE, callback, userdata, objMgrFilter);
 
6764
}
 
6765
 
 
6766
/*****************************************************************************
 
6767
*
 
6768
*   GetNextDescriptorUnindexed (bsp, choice, curr)
 
6769
*       After AssignIDsInEntity, gets next descriptor up the set hierarchy.
 
6770
*
 
6771
*****************************************************************************/
 
6772
 
 
6773
NLM_EXTERN SeqDescrPtr GetNextDescriptorUnindexed (
 
6774
  BioseqPtr bsp,
 
6775
  Uint1 choice,
 
6776
  SeqDescrPtr curr
 
6777
)
 
6778
 
 
6779
{
 
6780
  BioseqSetPtr   bssp = NULL;
 
6781
  ObjValNodePtr  ovp;
 
6782
  SeqDescrPtr    sdp;
 
6783
 
 
6784
  if (bsp == NULL || choice == 0) return NULL;
 
6785
 
 
6786
  if (curr == NULL) {
 
6787
    sdp = bsp->descr;
 
6788
    curr = sdp;
 
6789
  } else {
 
6790
    sdp = curr->next;
 
6791
  }
 
6792
  while (sdp != NULL) {
 
6793
    if (sdp->choice == choice) return sdp;
 
6794
    sdp = sdp->next;
 
6795
  }
 
6796
 
 
6797
  if (curr == NULL || curr->extended == 0) return NULL;
 
6798
  ovp = (ObjValNodePtr) curr;
 
6799
  if (ovp->idx.parenttype == OBJ_BIOSEQ) {
 
6800
    bsp = (BioseqPtr) ovp->idx.parentptr;
 
6801
    if (bsp == NULL) return NULL;
 
6802
    if (bsp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
 
6803
    bssp = (BioseqSetPtr) ovp->idx.parentptr;
 
6804
  } else if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
 
6805
    bssp = (BioseqSetPtr) ovp->idx.parentptr;
 
6806
    if (bssp == NULL) return NULL;
 
6807
    if (bssp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
 
6808
    bssp = (BioseqSetPtr) ovp->idx.parentptr;
 
6809
  } else return NULL;
 
6810
 
 
6811
  while (bssp != NULL) {
 
6812
    for (sdp = bssp->descr; sdp != NULL; sdp = sdp->next) {
 
6813
      if (sdp->choice == choice) return sdp;
 
6814
     }
 
6815
     if (bssp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
 
6816
     bssp = (BioseqSetPtr) bsp->idx.parentptr;
 
6817
  }
 
6818
  return NULL;
 
6819
}
 
6820
 
 
6821
typedef struct getptrforid {
 
6822
  Uint2    entityID;
 
6823
  Uint2    itemID;
 
6824
  Uint2    itemtype;
 
6825
  Pointer  dataptr;
 
6826
} GetPtrForId, PNTR GetPtrForIdPtr;
 
6827
 
 
6828
static Boolean GetPointerProc (GatherObjectPtr gop)
 
6829
 
 
6830
{
 
6831
  GetPtrForIdPtr  gfp;
 
6832
 
 
6833
  if (gop == NULL) return TRUE;
 
6834
  gfp = (GetPtrForIdPtr) gop->userdata;
 
6835
  if (gfp == NULL) return TRUE;
 
6836
  if (gfp->itemID != gop->itemID || gfp->itemtype != gop->itemtype) return TRUE;
 
6837
  gfp->dataptr = gop->dataptr;
 
6838
  return TRUE;
 
6839
}
 
6840
 
 
6841
NLM_EXTERN Pointer LIBCALL GetPointerForIDs (Uint2 entityID, Uint2 itemID, Uint2 itemtype)
 
6842
 
 
6843
{
 
6844
  GetPtrForId  gfi;
 
6845
  Boolean      objMgrFilter [OBJ_MAX];
 
6846
 
 
6847
  if (itemtype >= OBJ_MAX) return NULL;
 
6848
 
 
6849
  MemSet ((Pointer) objMgrFilter, FALSE, sizeof (objMgrFilter));
 
6850
  objMgrFilter [itemtype] = TRUE;
 
6851
  gfi.entityID = entityID;
 
6852
  gfi.itemID = itemID;
 
6853
  gfi.itemtype = itemtype;
 
6854
  gfi.dataptr = NULL;
 
6855
 
 
6856
  GatherObjectsInEntity (entityID, 0, NULL, GetPointerProc, &gfi, objMgrFilter);
 
6857
 
 
6858
  return gfi.dataptr;
 
6859
}
 
6860
 
 
6861
/*****************************************************************************
 
6862
*
 
6863
*   DeleteMarkedObjects (entityID, datatype, dataptr)
 
6864
*       Unlinks and removes all objects whose GatherIndex.deleteme flag is not 0.
 
6865
*
 
6866
*****************************************************************************/
 
6867
 
 
6868
static void DeleteMarkedSeqFeat (SeqFeatPtr sfp, Pointer PNTR prevlink)
 
6869
 
 
6870
{
 
6871
  SeqFeatPtr  next;
 
6872
 
 
6873
  while (sfp != NULL) {
 
6874
    next = sfp->next;
 
6875
 
 
6876
    if (sfp->idx.deleteme != 0) {
 
6877
      *prevlink = sfp->next;
 
6878
      sfp->next = NULL;
 
6879
      SeqFeatFree (sfp);
 
6880
    } else {
 
6881
      sfp->idx.prevlink = prevlink;
 
6882
      prevlink = (Pointer PNTR) &(sfp->next);
 
6883
    }
 
6884
 
 
6885
    sfp = next;
 
6886
  }
 
6887
}
 
6888
 
 
6889
static void DeleteMarkedSeqAlign (SeqAlignPtr sap, Pointer PNTR prevlink)
 
6890
 
 
6891
{
 
6892
  SeqAlignPtr  next;
 
6893
 
 
6894
  while (sap != NULL) {
 
6895
    next = sap->next;
 
6896
 
 
6897
    if (sap->idx.deleteme != 0) {
 
6898
      *prevlink = sap->next;
 
6899
      sap->next = NULL;
 
6900
      SeqAlignFree (sap);
 
6901
    } else {
 
6902
      sap->idx.prevlink = prevlink;
 
6903
      prevlink = (Pointer PNTR) &(sap->next);
 
6904
    }
 
6905
 
 
6906
    sap = next;
 
6907
  }
 
6908
}
 
6909
 
 
6910
static void DeleteMarkedSeqGraph (SeqGraphPtr sgp, Pointer PNTR prevlink)
 
6911
 
 
6912
{
 
6913
  SeqGraphPtr  next;
 
6914
 
 
6915
  while (sgp != NULL) {
 
6916
    next = sgp->next;
 
6917
 
 
6918
    if (sgp->idx.deleteme != 0) {
 
6919
      *prevlink = sgp->next;
 
6920
      sgp->next = NULL;
 
6921
      SeqGraphFree (sgp);
 
6922
    } else {
 
6923
      sgp->idx.prevlink = prevlink;
 
6924
      prevlink = (Pointer PNTR) &(sgp->next);
 
6925
    }
 
6926
 
 
6927
    sgp = next;
 
6928
  }
 
6929
}
 
6930
 
 
6931
static void DeleteMarkedSeqAnnot (SeqAnnotPtr sap, Pointer PNTR prevlink)
 
6932
 
 
6933
{
 
6934
  SeqAnnotPtr  next;
 
6935
 
 
6936
  while (sap != NULL) {
 
6937
    next = sap->next;
 
6938
 
 
6939
    if (sap->idx.deleteme == 0) {
 
6940
      switch (sap->type) {
 
6941
        case 1 :
 
6942
          DeleteMarkedSeqFeat ((SeqFeatPtr) sap->data, (Pointer PNTR) &(sap->data));
 
6943
          break;
 
6944
        case 2 :
 
6945
          DeleteMarkedSeqAlign ((SeqAlignPtr) sap->data, (Pointer PNTR) &(sap->data));
 
6946
          break;
 
6947
        case 3 :
 
6948
          DeleteMarkedSeqGraph ((SeqGraphPtr) sap->data, (Pointer PNTR) &(sap->data));
 
6949
          break;
 
6950
        default :
 
6951
          break;
 
6952
      }
 
6953
      if (sap->data == NULL) {
 
6954
        sap->idx.deleteme = 1;
 
6955
      }
 
6956
    }
 
6957
 
 
6958
    if (sap->idx.deleteme != 0) {
 
6959
      *prevlink = sap->next;
 
6960
      sap->next = NULL;
 
6961
      SeqAnnotFree (sap);
 
6962
    } else {
 
6963
      sap->idx.prevlink = prevlink;
 
6964
      prevlink = (Pointer PNTR) &(sap->next);
 
6965
    }
 
6966
  
 
6967
    sap = next;
 
6968
  }
 
6969
}
 
6970
 
 
6971
static void DeleteMarkedSeqDescr (SeqDescrPtr sdp, Pointer PNTR prevlink)
 
6972
 
 
6973
{
 
6974
  SeqDescrPtr    next;
 
6975
  ObjValNodePtr  ovp;
 
6976
 
 
6977
  while (sdp != NULL) {
 
6978
    next = sdp->next;
 
6979
 
 
6980
    ovp = (ObjValNodePtr) sdp;
 
6981
    if (sdp->extended != 0 && ovp->idx.deleteme != 0) {
 
6982
      *prevlink = sdp->next;
 
6983
      sdp->next = NULL;
 
6984
      SeqDescFree (sdp);
 
6985
    } else {
 
6986
      if (sdp->extended != 0) {
 
6987
        ovp->idx.prevlink = prevlink;
 
6988
      }
 
6989
      prevlink = (Pointer PNTR) &(sdp->next);
 
6990
    }
 
6991
 
 
6992
    sdp = next;
 
6993
  }
 
6994
}
 
6995
 
 
6996
static void DeleteMarkedSeqEntry (SeqEntryPtr sep, Pointer PNTR prevlink)
 
6997
 
 
6998
{
 
6999
  BioseqPtr     bsp;
 
7000
  BioseqSetPtr  bssp;
 
7001
  SeqEntryPtr   next;
 
7002
  Boolean       unlink;
 
7003
 
 
7004
  while (sep != NULL) {
 
7005
    next = sep->next;
 
7006
    unlink = FALSE;
 
7007
    bsp = NULL;
 
7008
    bssp = NULL;
 
7009
 
 
7010
    if (IS_Bioseq (sep)) {
 
7011
 
 
7012
      bsp = (BioseqPtr) sep->data.ptrvalue;
 
7013
      if (bsp != NULL) {
 
7014
        if (bsp->idx.deleteme != 0) {
 
7015
          unlink = TRUE;
 
7016
        } else {
 
7017
          DeleteMarkedSeqDescr (bsp->descr, (Pointer PNTR) &(bsp->descr));
 
7018
          DeleteMarkedSeqAnnot (bsp->annot, (Pointer PNTR) &(bsp->annot));
 
7019
        }
 
7020
      }
 
7021
 
 
7022
    } else if (IS_Bioseq_set (sep)) {
 
7023
 
 
7024
      bssp = (BioseqSetPtr) sep->data.ptrvalue;
 
7025
      if (bssp != NULL) {
 
7026
        if (bssp->idx.deleteme != 0) {
 
7027
          unlink = TRUE;
 
7028
        } else {
 
7029
          DeleteMarkedSeqDescr (bssp->descr, (Pointer PNTR) &(bssp->descr));
 
7030
          DeleteMarkedSeqAnnot (bssp->annot, (Pointer PNTR) &(bssp->annot));
 
7031
          DeleteMarkedSeqEntry (bssp->seq_set, (Pointer PNTR) &(bssp->seq_set));
 
7032
        }
 
7033
      }
 
7034
    }
 
7035
    if (unlink) {
 
7036
      *prevlink = sep->next;
 
7037
      sep->next = NULL;
 
7038
      SeqEntryFree (sep);
 
7039
    } else {
 
7040
      if (bsp != NULL) {
 
7041
        bsp->idx.prevlink = prevlink;
 
7042
      } else if (bssp != NULL) {
 
7043
        bssp->idx.prevlink = prevlink;
 
7044
      }
 
7045
      prevlink = (Pointer PNTR) &(sep->next);
 
7046
    }
 
7047
    sep = next;
 
7048
  }
 
7049
}
 
7050
 
 
7051
NLM_EXTERN Boolean DeleteMarkedObjects (Uint2 entityID, Uint2 datatype, Pointer dataptr)
 
7052
 
 
7053
{
 
7054
  BioseqPtr      bsp;
 
7055
  BioseqSetPtr   bssp;
 
7056
  ObjMgrDataPtr  omdp;
 
7057
  ObjMgrPtr      omp;
 
7058
  SeqEntryPtr    sep = NULL;
 
7059
  SeqSubmitPtr   ssp;
 
7060
 
 
7061
  if (entityID > 0) {
 
7062
    omp = ObjMgrReadLock ();
 
7063
    omdp = ObjMgrGetDataStruct (omp, entityID);
 
7064
    ObjMgrUnlock();
 
7065
    if (omdp == NULL) return FALSE;
 
7066
    if (omdp->choicetype == OBJ_SEQENTRY) {
 
7067
      datatype = omdp->choicetype;
 
7068
      dataptr = omdp->choice;
 
7069
    } else {
 
7070
      datatype = omdp->datatype;
 
7071
      dataptr = omdp->dataptr;
 
7072
    }
 
7073
  }
 
7074
 
 
7075
  if (datatype == 0 || dataptr == NULL) return FALSE;
 
7076
 
 
7077
  switch (datatype) {
 
7078
    case OBJ_SEQENTRY :
 
7079
      sep = (SeqEntryPtr) dataptr;
 
7080
      break;
 
7081
    case OBJ_BIOSEQ :
 
7082
      bsp = (BioseqPtr) dataptr;
 
7083
      sep = bsp->seqentry;
 
7084
      break;
 
7085
    case OBJ_BIOSEQSET :
 
7086
      bssp = (BioseqSetPtr) dataptr;
 
7087
      sep = bssp->seqentry;
 
7088
      break;
 
7089
    case OBJ_SEQSUB :
 
7090
      ssp = (SeqSubmitPtr) dataptr;
 
7091
      if (ssp->datatype == 1) {
 
7092
        sep = (SeqEntryPtr) ssp->data;
 
7093
      }
 
7094
      break;
 
7095
    default :
 
7096
      return FALSE;
 
7097
  }
 
7098
 
 
7099
  if (sep == NULL) return FALSE;
 
7100
 
 
7101
  DeleteMarkedSeqEntry (sep, (Pointer PNTR) &sep);
 
7102
 
 
7103
  return TRUE;
 
7104
}
 
7105