NCBI C Toolkit Cross Reference

C/cn3d/cn3dstyl.c


  1 /*   $Id: cn3dstyl.c,v 6.10 2000/05/10 14:15:40 thiessen Exp $
  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:  $Id: cn3dstyl.c,v 6.10 2000/05/10 14:15:40 thiessen Exp $
 27 *
 28 * Author: Yanli Wang
 29 *
 30 * Version Creation Date: 2/19/2000
 31 *
 32 * File Description: code to handle special styles/features
 33 *
 34 * Modifications:
 35 * --------------------------------------------------------------------------
 36 * $Log: cn3dstyl.c,v $
 37 * Revision 6.10  2000/05/10 14:15:40  thiessen
 38 * fix minor GUI bug in Annotate panel
 39 *
 40 * Revision 6.9  2000/04/20 23:27:45  lewisg
 41 * misc bug fixes
 42 *
 43 * Revision 6.8  2000/04/17 21:46:56  lewisg
 44 * do not do double index on viewmgr update, rename menus
 45 *
 46 * Revision 6.7  2000/03/22 23:17:50  thiessen
 47 * added ability to save ARS in ASN1
 48 *
 49 * Revision 6.6  2000/03/17 22:48:59  thiessen
 50 * fix for multi-chain / multi-model features ; added feature-move ; misc bug fixes
 51 *
 52 * Revision 6.5  2000/03/13 16:04:26  thiessen
 53 * re-implementation of features
 54 *
 55 * Revision 6.4  2000/03/08 21:46:15  lewisg
 56 * cn3d saves viewport, misc bugs
 57 *
 58 * Revision 6.3  2000/03/01 16:17:55  thiessen
 59 * improved handling of colors; many small fixes
 60 *
 61 * Revision 6.2  2000/02/26 00:01:40  thiessen
 62 * OpenGL improvements, progress on cleanup of Show/Hide
 63 *
 64 * Revision 6.1  2000/02/19 21:25:58  thiessen
 65 * split of cn3dmodl into cn3dmodl and cn3dstyl
 66 *
 67 *
 68 *
 69 * ==========================================================================
 70 */
 71 
 72 #include <ncbi.h>
 73 #ifdef _OPENGL
 74 #include <shim3d.h>
 75 #else
 76 #include <viewer3d.h>
 77 #endif
 78 #include <cn3dmain.h>
 79 #include <math.h>
 80 #include <mmdbapi.h>
 81 #include <mmdbapi1.h>
 82 #include <mmdbapi2.h>
 83 #include <mmdbapi3.h>
 84 #include <mmdbapi4.h>
 85 #include <algorend.h>
 86 #include <cn3dmsg.h>
 87 #include <salmedia.h>
 88 #include <salutil.h>
 89 #include <cn3dopen.h>
 90 #include <objmime.h>
 91 #include <cn3dshim.h>
 92 #include <cn3dstyl.h>
 93 
 94 
 95 typedef struct special_feature_info {
 96     PARS parsSpecial;
 97     Boolean isOn;
 98     CharPtr name, description;
 99     /* parallel lists of models and locations this feature applies to */
100     ValNodePtr pvnModels; /* data.ptrvalue holds PMSD */
101     ValNodePtr pvnLocations; /* data.ptrvalue holds BiostrucFeaturePtr->Location_location */
102 } SpecialFeatureInfo, PNTR SpecialFeatureInfoPtr;
103 
104 typedef ValNodePtr SpecialFeaturePtr;
105 
106 static void LIBCALL ResetModelCtrls(void);
107 
108 static ValNodePtr GetBiostrucFeatureLocationForHihglightedResidues(PDNMS pdnmsThis,
109                                                                   Int2 iFeature);
110 static void Cn3DApplyUserDefinedFeatureToMGD(PMSD pmsdThis, ValNodePtr llp,
111                                       Int2 iFeature, SpecialFeatureInfoPtr sfip);
112 
113 
114 static ENUM_ALIST(empty_alist)
115   {"              ",     1},
116 END_ENUM_ALIST
117 
118 static ENUM_ALIST(all_render_alist)
119   {"Wireframe",          1},
120   {"Tubes",              2},
121   {"Ball & Stick",       3},
122   {"Fat Tubes",          4},
123   {"Space Fill   ",      5},
124 END_ENUM_ALIST
125 
126 static ENUM_ALIST(all_color_alist)
127   {"red",           1},
128   {"green",         2},
129   {"magenta",       3},
130   {"sky",           4},
131   {"purple",        5},
132   {"Select...",     6},
133 END_ENUM_ALIST
134 
135 static EnumFieldAssocPtr renderAlist[4] =
136     { all_render_alist, all_render_alist, all_render_alist, all_render_alist };
137 
138 static EnumFieldAssocPtr colorAlist[4] =
139     { all_color_alist, all_color_alist, all_color_alist, all_color_alist };
140 
141 static ButtoN Cn3D_lModelOnOffItem[4]; /* pieces parts to draw */
142 static PopuP Cn3D_pupModelPBB;  /* protein backbone options */
143 static PopuP Cn3D_pupModelNABB; /* nucl. acid bb options */
144 static PopuP Cn3D_pupModelStyleItem;
145 static PopuP Cn3D_pupModelRenderStyle[4];
146 static PopuP Cn3D_pupModelColorStyle[4];
147 static TexT FeatureTitle;
148 static TexT FeatureDescription;
149 static ButtoN bResetFeatureTitle;
150 
151 static ButtoN Cn3D_lOnOffLabel[4];
152 static PopuP Cn3D_pupLabelAA;
153 static PopuP Cn3D_pupLabelNT;
154 static PopuP Cn3D_bLName[4];
155 static ButtoN Cn3D_bLNum[4];
156 static ButtoN Cn3D_bLWhite[4];
157 #ifndef _OPENGL
158 static ButtoN Cn3D_bLTop[4];
159 static PopuP Cn3D_pupLabelSize[4];
160 #endif
161 
162 static ButtoN Cn3D_bModelApply;
163 
164 static ButtoN bFeatureAdd;
165 static ButtoN bFeatureMove;
166 static ButtoN bFeatureDelete;
167 static ButtoN bFeatureEdit;
168 static LisT Cn3D_lFeaturesEdited;
169 static LisT Cn3D_lFeaturesOnOff;
170 
171 static SpecialFeaturePtr sfpGlobal = NULL;
172 static SpecialFeaturePtr sfpThis_head = NULL, sfpThis_tail = NULL;
173 static PARS parsSpecial = NULL;
174 static Byte iNumFeatures = 0, iEditedFeature = 0;
175 
176 
177 /*-----------------------------------------------*/
178 
179 
180 /*---------------------------------------------------------*/
181 static void Cn3D_SyncMenuHighlightWithOnOff(void)
182 {
183     SpecialFeaturePtr sfpThis = NULL;
184     SpecialFeatureInfoPtr sfipThis = NULL;
185     Int4 iCount = 1;
186 
187     Reset(Cn3D_lFeaturesOnOff);
188 
189     sfpThis = sfpGlobal;
190     while (sfpThis) {
191         sfipThis = sfpThis->data.ptrvalue;
192         ListItem(Cn3D_lFeaturesOnOff, (CharPtr) sfipThis->name);
193         SetItemStatus(Cn3D_lFeaturesOnOff, iCount, sfipThis->isOn);
194         iCount++;
195         sfpThis = sfpThis->next;
196     }
197 }
198 
199 /*---------------------------------------------------------*/
200 static void Cn3D_FeatureOnOffProc(LisT l)
201 {
202     SpecialFeaturePtr sfpThis = NULL;
203     SpecialFeatureInfoPtr sfipThis = NULL;
204     Int4 iCount = 1;
205 
206     sfpThis = sfpGlobal;
207     while (sfpThis) {
208         sfipThis = sfpThis->data.ptrvalue;
209         sfipThis->isOn = GetItemStatus(Cn3D_lFeaturesOnOff, iCount);
210         iCount++;
211         sfpThis = sfpThis->next;
212     }
213 }
214 
215 /*---------------------------------------------------------*/
216 static Int2 GetRenderItemIndex(Int2 k)
217 {
218     Int2 i = 1;
219 
220     switch (k) {
221     case R_WIRE:
222         i = 1;
223         break;
224     case R_STICK:
225         i = 2;
226         break;
227     case R_BALLNSTICK:
228         i = 3;
229         break;
230     case R_THICKWIRE:
231         i = 4;
232         break;
233     case R_SPACE:
234         i = 5;
235         break;
236     default:
237         ;
238     }
239 
240     return i;
241 }
242 
243 /*----------------------------------------------*/
244 static Int2 GetCn3d_PaletteRGBIndex(Uint1Ptr rgb)
245 {
246     Int2 iCount = 0, iColor = 0;
247 
248     for (iCount = 0; iCount < CN3D_COLOR_MAX; iCount++) {
249         if (*rgb == Cn3d_PaletteRGB[iCount][0] && 
250             *(rgb + 1) == Cn3d_PaletteRGB[iCount][1] &&
251             *(rgb + 2) == Cn3d_PaletteRGB[iCount][2]) {
252             iColor = iCount;
253             break;
254         }
255     }
256     return (iColor);
257 }
258 
259 /*---------------------------------------------------------*/
260 static Int2 GetColorItemIndex(Uint1 *rgb)
261 {
262     Int2 i;
263 
264     switch (GetCn3d_PaletteRGBIndex(rgb)) {
265     case C_red:
266         i = 1;
267         break;
268     case C_green:
269         i = 2;
270         break;
271     case C_magenta:
272         i = 3;
273         break;
274     case C_sky:
275         i = 4;
276         break;
277     case C_purple:
278         i = 5;
279         break;
280     default:
281         i = 6;
282     }
283     return i;
284 }
285 
286 /*---------------------------------------------------------*/
287 static void UpdateEditFeatureList()
288 {
289     SpecialFeaturePtr sfpThis = NULL;
290     SpecialFeatureInfoPtr sfipThis = NULL;
291 
292     Reset(Cn3D_lFeaturesEdited);
293     sfpThis = sfpGlobal;
294     while (sfpThis) {
295         sfipThis = sfpThis->data.ptrvalue;
296         ListItem(Cn3D_lFeaturesEdited, (CharPtr) sfipThis->name);
297         sfpThis = sfpThis->next;
298     }
299     SetValue(Cn3D_lFeaturesEdited, 0);
300 }
301 
302 /*---------------------------------------------------------*/
303 void LIBCALLBACK DecrementFeatureID(PFB pfbThis, Int4 unused,
304                                     Int4 iRemovedFeatureID, Pointer ptr)
305 {
306     ValNodePtr pvn = ((PMGD) pfbThis)->pvnPARSList;
307     while (pvn && pvn->choice > iRemovedFeatureID) {
308         pvn->choice--;
309         pvn = pvn->next;
310     }
311 }
312 
313 /*---------------------------------------------------------*/
314 /* if a feature is removed, renumber later (higher id) features so
315    that feature id's remain consecutive */
316 static void CollapseFeatureIDs(Int4 iRemovedFeatureID)
317 {
318     SpecialFeaturePtr sfpThis = sfpGlobal;
319     PDNMS pdnmsMaster = NULL, pdnmsSlave = NULL;
320 
321     /* renumber in feature list */
322     while (sfpThis) {
323         if (sfpThis->choice > iRemovedFeatureID)
324             sfpThis->choice--;
325         sfpThis = sfpThis->next;
326     }
327 
328     /* renumber id's in MG lists */
329     pdnmsMaster = GetSelectedModelstruc();
330     TraverseGraphs(pdnmsMaster, 0, iRemovedFeatureID, NULL, DecrementFeatureID);
331     pdnmsSlave = ((PMSD) pdnmsMaster->data.ptrvalue)->pdnmsSlaves;
332     while (pdnmsSlave) {
333         TraverseGraphs(pdnmsSlave, 0, iRemovedFeatureID, NULL, DecrementFeatureID);
334         pdnmsSlave = pdnmsSlave->next;
335     }
336 }
337 
338 /*---------------------------------------------------------*/
339 void LIBCALLBACK RemovePARSFromMGD(PFB pfbThis, Int4 unused,
340                                    Int4 iFeature, Pointer ptr)
341 {
342     PMGD pmgdThis = (PMGD) pfbThis;
343 
344     if (!pmgdThis) return;
345     ValNodeExtract(&(pmgdThis->pvnPARSList), iFeature);
346 }
347 
348 /*---------------------------------------------------------*/
349 /* add to list, always maintaining descending order of "choice" (for now) */
350 static void AddPARSToMGD(PMGD pmgdThis, Int4 iFeature, PARS pars)
351 {
352     ValNodePtr pvn, before, after;
353 
354     if (!pmgdThis) return;
355    
356     if (pmgdThis->pvnPARSList->choice < iFeature) { /* add to head */
357         pvn = ValNodeNew(NULL);
358         pvn->choice = iFeature;
359         pvn->data.ptrvalue = (VoidPtr) pars;
360         pvn->next = pmgdThis->pvnPARSList;
361         pmgdThis->pvnPARSList = pvn;
362         return;
363     }
364     for (before = pmgdThis->pvnPARSList; before; before = before->next) {
365         after = before->next;
366         if (before->choice == iFeature || after->choice == iFeature)
367             return; /* already present */
368         if (after->choice < iFeature) {
369             pvn = ValNodeNew(NULL);
370             pvn->choice = iFeature;
371             pvn->data.ptrvalue = (VoidPtr) pars;
372             pvn->next = after;
373             before->next = pvn;
374             return;
375         }
376     }
377 }
378 
379 /*---------------------------------------------------------*/
380 static void RemoveFeatureFromAllMGDs(Int4 iFeature)
381 {
382     PDNMS pdnmsMaster = NULL, pdnmsSlave = NULL;
383 
384     pdnmsMaster = GetSelectedModelstruc();
385     if (!pdnmsMaster) return;
386 
387     TraverseGraphs(pdnmsMaster, 0, iFeature, NULL, RemovePARSFromMGD);
388     pdnmsSlave = ((PMSD) pdnmsMaster->data.ptrvalue)->pdnmsSlaves;
389     while (pdnmsSlave) {
390         TraverseGraphs(pdnmsSlave, 0, iFeature, NULL, RemovePARSFromMGD);
391         pdnmsSlave = pdnmsSlave->next;
392     }
393 }
394 
395 /*---------------------------------------------------------*/
396 static Boolean Cn3D_CheckHLStatus(void)
397 {
398     PDNMS pdnmsThis = NULL, pdnmsSlave = NULL;
399     PMSD pmsdMaster = NULL, pmsdSlave = NULL;
400     PDNMM pdnmmHead = NULL;
401     PMMD pmmdThis = NULL;
402     PDNMG pdnmgThis = NULL;
403     PMGD pmgdThis = NULL;
404 
405     pdnmsThis = GetSelectedModelstruc();
406     if (pdnmsThis)
407         pmsdMaster = (PMSD) pdnmsThis->data.ptrvalue;
408     else
409         return FALSE;
410 
411     pdnmmHead = pmsdMaster->pdnmmHead;
412     while (pdnmmHead) {
413         pmmdThis = pdnmmHead->data.ptrvalue;
414         if (pmmdThis) {
415             pdnmgThis = pmmdThis->pdnmgHead;
416             while (pdnmgThis) {
417                 pmgdThis = pdnmgThis->data.ptrvalue;
418                 if (!(IsGraphAminoAcid(pmgdThis) || IsGraphNABase(pmgdThis)))
419                     break; /* only allow features on protein & NA residues for now */
420                 if (pmgdThis && pmgdThis->bHighlighted == 1) {
421                     return TRUE;
422                 }
423                 pdnmgThis = pdnmgThis->next;
424             }
425         }
426         pdnmmHead = pdnmmHead->next;
427     }
428 
429     pdnmsSlave = pmsdMaster->pdnmsSlaves;
430     while (pdnmsSlave) {
431         pmsdSlave = (PMSD) pdnmsSlave->data.ptrvalue;
432         pdnmmHead = pmsdSlave->pdnmmHead;
433         while (pdnmmHead) {
434             pmmdThis = pdnmmHead->data.ptrvalue;
435             if (pmmdThis) {
436                 pdnmgThis = pmmdThis->pdnmgHead;
437                 while (pdnmgThis) {
438                     pmgdThis = pdnmgThis->data.ptrvalue;
439                     if (!(IsGraphAminoAcid(pmgdThis) || IsGraphNABase(pmgdThis)))
440                         break;
441                     if (pmgdThis && pmgdThis->bHighlighted == 1) {
442                         return TRUE;
443                     }
444                     pdnmgThis = pdnmgThis->next;
445                 }
446             }
447             pdnmmHead = pdnmmHead->next;
448         }
449         pdnmsSlave = pdnmsSlave->next;
450     }
451 
452     return FALSE;
453 }
454 
455 /*---------------------------------------*/
456 static SpecialFeatureInfoPtr GetThisSpecialAlgorRenderSet(Int2 id)
457 {
458     SpecialFeaturePtr sfpThis = NULL;
459     SpecialFeatureInfoPtr sfipThis = NULL;
460 
461     sfpThis = sfpGlobal;
462     while (sfpThis) {
463         if (sfpThis->choice == id) {
464             return sfpThis->data.ptrvalue;
465         }
466         sfpThis = sfpThis->next;
467     }
468 
469     return NULL;
470 }
471 
472 /*---------------------------------------------------------*/
473 static ValNodePtr CopyLocation(ValNodePtr locOld)
474 {
475     ValNodePtr locNew;
476     ChemGraphPntrsPtr pcgpNew, pcgpOld = (ChemGraphPntrsPtr) locOld->data.ptrvalue;
477     ValNodePtr rspNew, rspOld = (ValNodePtr) pcgpOld->data.ptrvalue;
478     ResidueIntervalPntrPtr rsipNew = NULL, rsipPrev = NULL, rsipNewHead,
479         rsipOld = (ResidueIntervalPntrPtr) rspOld->data.ptrvalue;
480 
481     while (rsipOld) {
482         rsipNew = ResidueIntervalPntrNew();
483         if (!rsipNew) return NULL;
484         MemCpy(rsipNew, rsipOld, sizeof(ResidueIntervalPntr));
485         rsipNew->next = NULL;
486         if (rsipPrev) 
487             rsipPrev->next = rsipNew;
488         else
489             rsipNewHead = rsipNew;
490         rsipPrev = rsipNew;
491         rsipOld = rsipOld->next;
492     }
493     rspNew = ValNodeNew(NULL);
494     if (!rspNew) return NULL;
495     MemCpy(rspNew, rspOld, sizeof(ValNode));
496     rspNew->data.ptrvalue = (VoidPtr) rsipNewHead;
497     pcgpNew = ValNodeNew(NULL);
498     if (!pcgpNew) return NULL;
499     MemCpy(pcgpNew, pcgpOld, sizeof(ValNode));
500     pcgpNew->data.ptrvalue = (VoidPtr) rspNew;
501     locNew = ValNodeNew(NULL);
502     if (!locNew) return NULL;
503     MemCpy(locNew, locOld, sizeof(ValNode));
504     locNew->data.ptrvalue = (VoidPtr) pcgpNew;
505     return locNew;
506 }
507 
508 /*---------------------------------------------------------*/
509 static void FreeLocations(ValNodePtr pvnLocations)
510 {
511     while (pvnLocations) {
512         ChemGraphPntrsPtr pcgpThis = pvnLocations->data.ptrvalue;
513         ValNodePtr rsp = pcgpThis->data.ptrvalue;
514         ResidueIntervalPntrPtr rsip = rsp->data.ptrvalue;
515         ResidueIntervalPntrFree(rsip);
516         rsp->data.ptrvalue = NULL;
517         ValNodeFree(rsp);
518         pcgpThis->data.ptrvalue = NULL;
519         ValNodeFree(pcgpThis);
520         pvnLocations = pvnLocations->next;
521     }
522 }
523 
524 /*---------------------------------------------------------*/
525 static SpecialFeatureInfoPtr SpecialFeatureInfoFree(SpecialFeatureInfoPtr sfipThis)
526 {
527     if (sfipThis->name)
528         MemFree(sfipThis->name);
529     if (sfipThis->description)
530         MemFree(sfipThis->description);
531     if (sfipThis->parsSpecial)
532         FreeAlgorRenderSet(sfipThis->parsSpecial);
533     if (sfipThis->pvnModels)
534         ValNodeFree(sfipThis->pvnModels);
535     if (sfipThis->pvnLocations)
536         FreeLocations(sfipThis->pvnLocations);
537     return MemFree(sfipThis);
538 }
539 
540 /*---------------------------------------------------------*/
541 static SpecialFeaturePtr LIBCALL SpecialFeatureFree(SpecialFeaturePtr sfpThis)
542 {
543     SpecialFeatureInfoPtr sfipThis = NULL;
544 
545     if (sfpThis == NULL)
546         return NULL;
547     sfipThis = sfpThis->data.ptrvalue;
548     if (sfipThis)
549         sfipThis = SpecialFeatureInfoFree(sfipThis);
550 
551     sfpThis->data.ptrvalue = NULL;
552     sfpThis = ValNodeFree(sfpThis);
553     return (sfpThis);
554 }
555 
556 /*---------------------------------------------------------*/
557 static SpecialFeatureInfoPtr LIBCALL SpecialFeatureInfoNew()
558 {
559     return (SpecialFeatureInfoPtr) MemNew(sizeof(SpecialFeatureInfo));
560 }
561 
562 /*--------------------------------------------------------*/
563 static SpecialFeatureInfoPtr GetEditedSpecialFeatureInfo(void)
564 {
565     Int4 iFeature = 0, iCount = 0;
566     SpecialFeatureInfoPtr sfipThis = NULL;
567     SpecialFeaturePtr sfpThis = NULL;
568 
569     iFeature = GetValue(Cn3D_lFeaturesEdited);
570     iCount = 0;
571 
572     sfpThis = sfpGlobal;
573     while (sfpThis) {
574         iCount++;
575         if (iFeature == iCount) {
576             sfipThis = sfpThis->data.ptrvalue;
577             iEditedFeature = sfpThis->choice;
578             return sfipThis;
579         }
580         sfpThis = sfpThis->next;
581     }
582     return NULL;
583 }
584 
585 /*---------------------------------------------------------*/
586 static PARS GetEditedSpecialFeatureInfoPAR(void)
587 {
588     SpecialFeatureInfoPtr sfipThis = NULL;
589     PARS parsThis = NULL;
590 
591     sfipThis = GetEditedSpecialFeatureInfo();
592     if (sfipThis) {
593         parsThis = sfipThis->parsSpecial;
594         if (parsThis)
595             return parsThis;
596         else {
597             return NULL;
598         }
599     }
600     return NULL;
601 }
602 
603 /*---------------------------------------------------------*/
604 static PARS GetNewSpecialAlgorRenderSet(void)
605 {
606     PARS pars = NULL;
607 
608     pars = NewStructureRenderSet();
609 
610     pars->PVirtualBBOn = TRUE;
611     pars->PPartialBBOn = FALSE;
612     pars->PCompleteBBOn = FALSE;
613 
614     pars->PBBColor = C_BYCHOICE;
615     pars->PResiduesOn = TRUE;
616     pars->PResColor = C_BYCHOICE;
617 
618     pars->NTVirtualBBOn = TRUE;
619     pars->NTPartialBBOn = FALSE;
620     pars->NTCompleteBBOn = FALSE;
621 
622     pars->NTBBColor = C_BYCHOICE;
623     pars->NTResiduesOn = TRUE;
624     pars->NTResColor = C_BYCHOICE;
625 
626     pars->PBBLabelStyle |= L_WHITE;
627     pars->NTBBLabelStyle |= L_WHITE;
628 
629     pars->PBBColRGB[0] = pars->PBBColRGB[1] = pars->PBBColRGB[2] =
630     pars->PResColRGB[0] = pars->PResColRGB[1] = pars->PResColRGB[2] =
631     pars->NTBBColRGB[0] = pars->NTBBColRGB[1] = pars->NTBBColRGB[2] =
632     pars->NTResColRGB[0] = pars->NTResColRGB[1] = pars->NTResColRGB[2] = 128;
633 
634     return pars;
635 }
636 
637 /*---------------------------------------------------------*/
638 PARS LIBCALL GetSpecialAlgorRenderSet(void)
639 {
640     SpecialFeaturePtr sfpThis = NULL;
641     PARS parsThis = NULL;
642     if (GetStatus(bFeatureEdit) || GetStatus(bFeatureMove)) {
643         return GetEditedSpecialFeatureInfoPAR();
644     }
645     
646     if (parsSpecial == NULL) {
647         parsSpecial = GetNewSpecialAlgorRenderSet();
648     }
649     return parsSpecial;
650 }
651 
652 /*---------------------------------------------------------*/
653 static void FeatureTitleProc(TexT b)
654 {
655     ResetModelCtrls();
656 }
657 
658 /*---------------------------------------------------------*/
659 static void ChangeSpecialRenderProc(PopuP p)
660 {
661     Int2 i = 0, j = 0, k = 0;
662     Uint1 r, g, b;
663     PARS pars = NULL;
664     UIEnum val;
665 
666     pars = GetSpecialAlgorRenderSet();
667     if (!pars)
668         return;
669 
670     pars->PResiduesOn = GetStatus(Cn3D_lModelOnOffItem[2]);
671     pars->NTResiduesOn = GetStatus(Cn3D_lModelOnOffItem[3]);
672 
673     pars->PVirtualBBOn = FALSE;
674     pars->PPartialBBOn = FALSE;
675     pars->PCompleteBBOn = FALSE;
676 
677     i = GetValue(Cn3D_pupModelPBB);
678     switch (i) {
679     case 1:
680         pars->PVirtualBBOn = TRUE; /* alpha c trace */
681         break;
682     case 2:
683         pars->PPartialBBOn = TRUE; /* partial atoms */
684         break;
685     case 3:
686         pars->PCompleteBBOn = TRUE; /* all atoms */
687         break;
688     default:;                  /* none */
689     }
690 
691     pars->NTVirtualBBOn = FALSE;
692     pars->NTPartialBBOn = FALSE;
693     pars->NTCompleteBBOn = FALSE;
694 
695     j = GetValue(Cn3D_pupModelNABB);
696     switch (j) {
697     case 1:
698         pars->NTVirtualBBOn = TRUE;
699         break;
700     case 2:
701         pars->NTPartialBBOn = TRUE;
702         break;
703     case 3:
704         pars->NTCompleteBBOn = TRUE;
705         break;
706     default:;
707     }
708 
709     for (i = 0; i < 4; i++) {
710         if (GetEnumPopup(Cn3D_pupModelColorStyle[i], colorAlist[i], &val)) {
711             j = (Int2) val;
712         } else {
713             j = 1;
714         }
715 
716         switch (j) {
717         case 1:
718             k = C_red;
719             break;
720         case 2:
721             k = C_green;
722             break;
723         case 3:
724             k = C_magenta;
725             break;
726         case 4:
727             k = C_sky;
728             break;
729         case 5:
730             k = C_purple;
731             break;
732         case 6:
733         default:
734             k = -1;
735         }
736 
737         if (k != -1 || Cn3D_pupModelColorStyle[i] == p) {
738 
739             if (k == -1) {
740                 Nlm_ChooseColorDialog(&r, &g, &b, FALSE);
741             } else {
742                 r = Cn3d_PaletteRGB[k][0];
743                 g = Cn3d_PaletteRGB[k][1];
744                 b = Cn3d_PaletteRGB[k][2];
745             }
746 
747             switch (i) {
748             case 0:                /* prot bb */
749                 pars->PBBColor = C_BYCHOICE;
750                 pars->PBBColRGB[0] = r;
751                 pars->PBBColRGB[1] = g;
752                 pars->PBBColRGB[2] = b;
753                 break;
754             case 1:                /* prot sc */
755                 pars->NTBBColor = C_BYCHOICE;
756                 pars->NTBBColRGB[0] = r;
757                 pars->NTBBColRGB[1] = g;
758                 pars->NTBBColRGB[2] = b;
759                 break;
760             case 2:                /* na bb */
761                 pars->PResColor = C_BYCHOICE;
762                 pars->PResColRGB[0] = r;
763                 pars->PResColRGB[1] = g;
764                 pars->PResColRGB[2] = b;
765                 break;
766             case 3:                /* na sc */
767                 pars->NTResColor = C_BYCHOICE;
768                 pars->NTResColRGB[0] = r;
769                 pars->NTResColRGB[1] = g;
770                 pars->NTResColRGB[2] = b;
771                 break;
772             }
773         }
774     }
775 
776     for (i = 0; i < 4; i++) {
777         if (GetEnumPopup(Cn3D_pupModelRenderStyle[i], renderAlist[i], &val)) {
778             j = (Int2) val;
779         } else {
780             j = 1;
781         }
782         switch (j) {
783         case 1:
784             k = R_WIRE;
785             break;
786         case 2:
787             k = R_STICK;
788             break;
789         case 3:
790             k = R_BALLNSTICK;
791             break;
792         case 4:
793             k = R_THICKWIRE;
794             break;
795         case 5:
796             k = R_SPACE;
797             break;
798         default:
799             ;
800         }
801         switch (i) {
802         case 0:                /* prot bb */
803             pars->PBBRender = k;
804             break;
805         case 1:                /* na bb */
806             pars->NTBBRender = k;
807             break;
808         case 2:                /* prot sc */
809             pars->PResRender = k;
810             break;
811         case 3:                /* na sc */
812             pars->NTResRender = k;
813             break;
814         default:
815             ;
816         }
817     }
818 }
819 
820 /*---------------------------------------------------------*/
821 static void ModelPopupOnOffProc(PopuP p)
822 {
823     ChangeSpecialRenderProc(p);
824 }
825 
826 /*---------------------------------------------------------*/
827 static void ModelButtonOnOffProc(ButtoN b)
828 {
829     ChangeSpecialRenderProc(NULL);
830 }
831 
832 /*---------------------------------------------------------*/
833 static PopuP ModelRenderStyle(GrouP h, Int2 i)
834 {
835     PopuP p;
836 
837     if (renderAlist[i] != empty_alist) {
838         p = PopupList(h, FALSE, ModelPopupOnOffProc);
839     } else {
840         p = PopupList(h, FALSE, NULL);
841     }
842     InitEnumPopup(p, renderAlist[i], NULL);
843     return p;
844 }
845 
846 /*---------------------------------------------------------*/
847 static PopuP ModelColorStyle(GrouP h, Int2 i)
848 {
849     PopuP p;
850 
851     if (colorAlist[i] != empty_alist) {
852         p = PopupList(h, FALSE, ModelPopupOnOffProc);
853     } else {
854         p = PopupList(h, FALSE, NULL);
855     }
856     InitEnumPopup(p, colorAlist[i], NULL);
857     return p;
858 
859 }
860 
861 /*---------------------------------------------------------*/
862 static void ChangeSpecialLabelsProc(void)
863 {
864     Int2 i = 0, k = 0, nameval = 0;
865     Uint1 codeval;
866     Boolean NumOn = FALSE, NameOn = FALSE, PDBOn = FALSE, WhiteOn =
867         FALSE, TopOn = FALSE;
868     PARS pars = NULL;
869 
870     pars = GetSpecialAlgorRenderSet();
871     if (!pars)
872         return;
873 
874     pars->PBBLabelInterval = (Uint1) GetValue(Cn3D_pupLabelAA);
875     pars->NTBBLabelInterval = (Uint1) GetValue(Cn3D_pupLabelNT);
876 
877     for (i = 0; i < 2; i++) {
878 
879         nameval = GetValue(Cn3D_bLName[i]);
880         switch (nameval) {
881         case 2:
882             codeval = (Uint1) L_3LETR;
883             break;
884         case 3:
885             codeval = (Uint1) L_1LETR;
886             break;
887         case 4:
888             codeval = (Uint1) L_PDB;
889             break;
890         case 1: default:
891             codeval = 0;
892         }
893         switch (i) {
894         case 0:                /* aa */
895             /* clear bits */
896             pars->PBBLabelStyle &= ~((Uint1) (L_3LETR | L_1LETR | L_PDB));
897             /* set bit */
898             pars->PBBLabelStyle |= codeval;
899             break;
900         case 1:                /* na   */
901             pars->NTBBLabelStyle &= ~((Uint1) (L_3LETR | L_1LETR | L_PDB));
902             pars->NTBBLabelStyle |= codeval;
903             break;
904         default: ;
905         }
906 
907         NameOn = (Boolean) (nameval > 1);
908         switch (i) {
909         case 0:                /* aa */
910             if (NameOn)
911                 pars->PBBLabelStyle |= (Uint1) L_NAME;
912             else
913                 pars->PBBLabelStyle &= (Uint1) ~L_NAME;
914             break;
915         case 1:                /* na   */
916             if (NameOn)
917                 pars->NTBBLabelStyle |= (Uint1) L_NAME;
918             else
919                 pars->NTBBLabelStyle &= (Uint1) ~L_NAME;
920             break;
921         default: ;
922         }
923 
924         NumOn = GetStatus(Cn3D_bLNum[i]);
925         switch (i) {
926         case 0:                /* aa */
927             if (NumOn)
928                 pars->PBBLabelStyle |= (Uint1) L_NUM;
929             else
930                 pars->PBBLabelStyle &= (Uint1) ~L_NUM;
931             break;
932         case 1:                /* na   */
933             if (NumOn)
934                 pars->NTBBLabelStyle |= (Uint1) L_NUM;
935             else
936                 pars->NTBBLabelStyle &= (Uint1) ~L_NUM;
937             break;
938         default: ;
939         }
940 
941         WhiteOn = GetStatus(Cn3D_bLWhite[i]);
942         switch (i) {
943         case 0:                /* aa */
944             if (WhiteOn)
945                 pars->PBBLabelStyle |= (Uint1) L_WHITE;
946             else
947                 pars->PBBLabelStyle &= (Uint1) ~L_WHITE;
948             break;
949         case 1:                /* na   */
950             if (WhiteOn)
951                 pars->NTBBLabelStyle |= (Uint1) L_WHITE;
952             else
953                 pars->NTBBLabelStyle &= (Uint1) ~L_WHITE;
954             break;
955         default: ;
956         }
957 
958 #ifndef _OPENGL
959         TopOn = GetStatus(Cn3D_bLTop[i]);
960         switch (i) {
961         case 0:                /* aa */
962             if (TopOn)
963                 pars->PBBLabelJust = pars->PBBLabelJust | (Uint1) LA_FRONT;
964             else
965                 pars->PBBLabelJust =
966                     pars->PBBLabelJust & (Uint1) ~ LA_FRONT;
967             break;
968         case 1:                /* na   */
969             if (TopOn)
970                 pars->NTBBLabelJust =
971                     pars->NTBBLabelJust | (Uint1) LA_FRONT;
972             else
973                 pars->NTBBLabelJust =
974                     pars->NTBBLabelJust & (Uint1) ~ LA_FRONT;
975             break;
976         default:
977             ;
978         }
979         k = (Int2) GetValue(Cn3D_pupLabelSize[i]);
980         switch (i) {
981         case 0:                /* prot bb */
982             pars->PBBLabelScale = k;
983             break;
984         case 1:                /* na bb */
985             pars->NTBBLabelScale = k;
986             break;
987         default:
988             ;
989         }
990 #endif
991     }
992 }
993 
994 /*---------------------------------------------------------*/
995 static void ModelLabelPopupOnOffProc(PopuP p)
996 {
997     ChangeSpecialLabelsProc();
998 }
999 
1000 /*---------------------------------------------------------*/
1001 static void ModelLabelButtonOnOffProc(ButtoN b)
1002 {
1003     ChangeSpecialLabelsProc();
1004 }
1005 
1006 /*---------------------------------------------------------*/
1007 static void ModelSetRenderCtrls(PARS pars)
1008 {
1009     Int2 i;
1010 
1011     if (!pars)
1012         return;
1013 
1014     i = 4;
1015     if (pars->PVirtualBBOn)
1016         i = 1;
1017     else if (pars->PPartialBBOn)
1018         i = 2;
1019     else if (pars->PCompleteBBOn)
1020         i = 3;
1021     SafeSetValue(Cn3D_pupModelPBB, i);
1022 
1023     i = 4;
1024     if (pars->NTVirtualBBOn)
1025         i = 1;
1026     else if (pars->NTPartialBBOn)
1027         i = 2;
1028     else if (pars->NTCompleteBBOn)
1029         i = 3;
1030     SafeSetValue(Cn3D_pupModelNABB, i);
1031 
1032     SafeSetStatus(Cn3D_lModelOnOffItem[2], pars->PResiduesOn);
1033     SafeSetStatus(Cn3D_lModelOnOffItem[3], pars->NTResiduesOn);
1034 
1035     i = GetRenderItemIndex(pars->PBBRender);
1036     SafeSetValue(Cn3D_pupModelRenderStyle[0], i);
1037     i = GetColorItemIndex(pars->PBBColRGB);
1038     SafeSetValue(Cn3D_pupModelColorStyle[0], i);
1039 
1040     i = GetRenderItemIndex(pars->NTBBRender);
1041     SafeSetValue(Cn3D_pupModelRenderStyle[1], i);
1042     i = GetColorItemIndex(pars->NTBBColRGB);
1043     SafeSetValue(Cn3D_pupModelColorStyle[1], i);
1044 
1045     i = GetRenderItemIndex(pars->PResRender);
1046     SafeSetValue(Cn3D_pupModelRenderStyle[2], i);
1047     i = GetColorItemIndex(pars->PResColRGB);
1048     SafeSetValue(Cn3D_pupModelColorStyle[2], i);
1049 
1050     i = GetRenderItemIndex(pars->NTResRender);
1051     SafeSetValue(Cn3D_pupModelRenderStyle[3], i);
1052     i = GetColorItemIndex(pars->NTResColRGB);
1053     SafeSetValue(Cn3D_pupModelColorStyle[3], i);
1054 }
1055 
1056 /*---------------------------------------------------------*/
1057 static void ModelSetLabelCtrls(PARS pars)
1058 {
1059     Int2 i = 0, val = 0, style = 0, size = 0;
1060 
1061     if (!pars)
1062         return;
1063 
1064     SafeSetValue(Cn3D_pupLabelAA, pars->PBBLabelInterval);
1065     SafeSetValue(Cn3D_pupLabelNT, pars->NTBBLabelInterval);
1066 
1067     SafeSetStatus(Cn3D_lOnOffLabel[2], pars->PTermLabelOn);
1068     SafeSetStatus(Cn3D_lOnOffLabel[3], pars->NTTermLabelOn);
1069 
1070     for (i = 0; i < 2; i++) {
1071         if (i == 0) {
1072             style = pars->PBBLabelStyle;
1073             size = pars->PBBLabelScale;
1074         } else {
1075             style = pars->NTBBLabelStyle;
1076             size = pars->NTBBLabelScale;
1077         }
1078         val = 1;
1079         if (style & L_NAME) {
1080             if (style & L_3LETR) {
1081                 val = 2;
1082             } else if (style & L_1LETR) {
1083                 val = 3;
1084             } else if (style & L_PDB) {
1085                 val = 4;
1086             }
1087         }
1088         SafeSetValue(Cn3D_bLName[i], val);
1089         SafeSetStatus(Cn3D_bLNum[i], (Boolean) (style & L_NUM));
1090         SafeSetStatus(Cn3D_bLWhite[i], (Boolean) (style & L_WHITE));
1091 #ifndef _OPENGL
1092         SafeSetStatus(Cn3D_bLTop[i], (Boolean) (style & (Uint1) LA_FRONT));
1093         SafeSetValue(Cn3D_pupLabelSize[i], size);
1094 #endif
1095     }
1096 }
1097 
1098 /*---------------------------------------------------------*/
1099 static void ModelResetLabelCtrls(void)
1100 {
1101     PARS pars = NULL;
1102 
1103     pars = GetSpecialAlgorRenderSet();
1104     if (!pars)
1105         return;
1106 
1107     ModelSetLabelCtrls(pars);
1108 }
1109 
1110 /*---------------------------------------------------------*/
1111 static void bFeatureAddAction(ButtoN b)
1112 {
1113     if (GetStatus(bFeatureAdd)) {
1114         SetStatus(bFeatureEdit, FALSE);
1115         SetStatus(bFeatureDelete, FALSE);
1116         SetStatus(bFeatureMove, FALSE);
1117         SafeSetValue(Cn3D_lFeaturesEdited, 0);
1118     }
1119 }
1120 
1121 /*---------------------------------------------------------*/
1122 static void bFeatureDeleteAction(ButtoN b)
1123 {
1124     if (GetStatus(bFeatureDelete)) {
1125         SetStatus(bFeatureEdit, FALSE);
1126         SetStatus(bFeatureAdd, FALSE);
1127         SetStatus(bFeatureMove, FALSE);
1128     }
1129 }
1130 
1131 /*---------------------------------------------------------*/
1132 static void lFeatureEditedAction(LisT l)
1133 {
1134     SpecialFeatureInfoPtr sfip = NULL;
1135     PARS parsThis = NULL;
1136     Int4 val = 0;
1137 
1138     if (GetStatus(bFeatureEdit) || GetStatus(bFeatureDelete) || GetStatus(bFeatureMove)) {
1139         sfip = GetEditedSpecialFeatureInfo();
1140         if (sfip) {
1141             SetTitle(FeatureTitle, sfip->name);
1142             SetTitle(FeatureDescription, sfip->description);
1143         }
1144         parsThis = GetEditedSpecialFeatureInfoPAR();
1145         ModelSetRenderCtrls(parsThis);
1146         ModelSetLabelCtrls(parsThis);
1147     }
1148 }
1149 
1150 /*---------------------------------------------------------*/
1151 static void bFeatureMoveAction(ButtoN b)
1152 {
1153     SpecialFeaturePtr sfpThis = NULL;
1154     SpecialFeatureInfoPtr sfip = NULL;
1155     PARS parsThis = NULL;
1156 
1157     if (GetStatus(bFeatureMove)) {
1158         SetStatus(bFeatureAdd, FALSE);
1159         SetStatus(bFeatureDelete, FALSE);
1160         SetStatus(bFeatureEdit, FALSE);
1161 
1162         sfip = GetEditedSpecialFeatureInfo();
1163         if (sfip) {
1164             SetTitle(FeatureTitle, sfip->name);
1165             SetTitle(FeatureDescription, sfip->description);
1166         }
1167         parsThis = GetEditedSpecialFeatureInfoPAR();
1168         ModelSetRenderCtrls(parsThis);
1169         ModelSetLabelCtrls(parsThis);
1170     }
1171 }
1172 
1173 /*---------------------------------------------------------*/
1174 static void bFeatureEditAction(ButtoN b)
1175 {
1176     SpecialFeaturePtr sfpThis = NULL;
1177     SpecialFeatureInfoPtr sfip = NULL;
1178     PARS parsThis = NULL;
1179 
1180     if (GetStatus(bFeatureEdit)) {
1181         SetStatus(bFeatureAdd, FALSE);
1182         SetStatus(bFeatureDelete, FALSE);
1183         SetStatus(bFeatureMove, FALSE);
1184 
1185         sfip = GetEditedSpecialFeatureInfo();
1186         if (sfip) {
1187             SetTitle(FeatureTitle, sfip->name);
1188             SetTitle(FeatureDescription, sfip->description);
1189         }
1190         parsThis = GetEditedSpecialFeatureInfoPAR();
1191         ModelSetRenderCtrls(parsThis);
1192         ModelSetLabelCtrls(parsThis);
1193     }
1194 }
1195 
1196 /*---------------------------------------------------------*/
1197  static ValNodePtr GetFeatureLocationForModel(SpecialFeatureInfoPtr sfip, PMSD pmsd)
1198  {
1199     ValNodePtr pvnLoc, pvnModel;
1200 
1201     for (pvnModel = sfip->pvnModels, pvnLoc = sfip->pvnLocations;
1202          pvnModel && pvnLoc;
1203          pvnModel = pvnModel->next, pvnLoc = pvnLoc->next) {
1204         if (pvnModel->data.ptrvalue == (VoidPtr) pmsd)
1205             return (ValNodePtr) pvnLoc->data.ptrvalue;
1206     }
1207     return NULL;
1208  }
1209 
1210 /*---------------------------------------------------------*/
1211 static void Cn3D_FeatureApplyProc(ButtoN b)
1212 {
1213     SpecialFeatureInfoPtr sfip = NULL;
1214     SpecialFeaturePtr sfpThis = NULL;
1215     PARS pars = NULL;
1216     PDNMS pdnmsThis, pdnmsSlave;
1217     PMSD pmsdThis;
1218     ValNodePtr pvnLoc;
1219 #ifdef _DEBUG
1220     int iCount = 0;
1221 #endif
1222 
1223     /* delete a feature */
1224     if (GetStatus(bFeatureDelete)) {
1225         SetStatus(bFeatureDelete, FALSE);
1226         if (sfpGlobal == NULL) return;
1227         sfip = GetEditedSpecialFeatureInfo();
1228         if (sfip == NULL) return;
1229         if (sfpGlobal->next == NULL) {
1230             sfpGlobal = SpecialFeatureFree(sfpGlobal);
1231         } else {
1232             sfpThis = ValNodeExtract(&sfpGlobal, iEditedFeature);
1233             sfpThis = SpecialFeatureFree(sfpThis);
1234         }
1235         RemoveFeatureFromAllMGDs(iEditedFeature);
1236         CollapseFeatureIDs(iEditedFeature);
1237         UpdateEditFeatureList();
1238         Cn3D_SyncMenuHighlightWithOnOff();
1239         iNumFeatures--;
1240         fnCn3D_RedrawWrapper(FALSE);
1241         return;
1242     }
1243 
1244     /* if add more move but nothing selected, return */
1245     if (GetStatus(bFeatureAdd) || GetStatus(bFeatureMove)) {
1246         if (!Cn3D_CheckHLStatus()) {
1247             SetStatus(bFeatureAdd, FALSE);
1248             SetStatus(bFeatureMove, FALSE);
1249             return;
1250         }
1251     }
1252 
1253     pars = GetSpecialAlgorRenderSet();
1254     if (!pars) {
1255         SetStatus(bFeatureEdit, FALSE);
1256         SetStatus(bFeatureAdd, FALSE);
1257         SetStatus(bFeatureMove, FALSE);
1258         return;
1259     }
1260     ChangeSpecialRenderProc(NULL);
1261     ChangeSpecialLabelsProc();
1262     pdnmsThis = GetSelectedModelstruc();
1263     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1264 
1265     if (GetStatus(bFeatureAdd) || GetStatus(bFeatureEdit) || GetStatus(bFeatureMove)) {
1266         Char str[1024];
1267 
1268         if (GetStatus(bFeatureEdit)) {
1269             sfip = GetEditedSpecialFeatureInfo();
1270         }
1271 
1272         else if (GetStatus(bFeatureMove)) {
1273             sfip = GetEditedSpecialFeatureInfo();
1274             RemoveFeatureFromAllMGDs(iEditedFeature);
1275             FreeLocations(sfip->pvnLocations);
1276             ValNodeFree(sfip->pvnModels);
1277         }
1278         
1279         else { /* add */
1280             sfip = SpecialFeatureInfoNew();
1281             sfip->parsSpecial = pars;
1282             iNumFeatures++;
1283             ValNodeAddPointer(&sfpGlobal, iNumFeatures, (VoidPtr) sfip);
1284             iEditedFeature= iNumFeatures;
1285         }
1286 
1287         sfip->isOn = TRUE;
1288 
1289         if (GetStatus(bFeatureAdd) || GetStatus(bFeatureMove)) {
1290             sfip->pvnLocations = sfip->pvnModels = NULL;
1291             pvnLoc = GetBiostrucFeatureLocationForHihglightedResidues(pdnmsThis, iEditedFeature);
1292             if (pvnLoc) {
1293                 ValNodeAddPointer(&(sfip->pvnLocations), 0, (VoidPtr) pvnLoc);
1294                 ValNodeAddPointer(&(sfip->pvnModels), 0, (VoidPtr) pmsdThis);
1295             }
1296             for (pdnmsSlave = pmsdThis->pdnmsSlaves; pdnmsSlave; pdnmsSlave = pdnmsSlave->next) {
1297                 pvnLoc = GetBiostrucFeatureLocationForHihglightedResidues(pdnmsSlave, iEditedFeature);
1298                 if (pvnLoc) {
1299                     ValNodeAddPointer(&(sfip->pvnLocations), 0, (VoidPtr) pvnLoc);
1300                     ValNodeAddPointer(&(sfip->pvnModels), 0, pdnmsSlave->data.ptrvalue);
1301                 }
1302             }
1303             ObjMgrDeSelectAll();
1304         }
1305 
1306         GetTitle(FeatureTitle, str, sizeof(str));
1307         sfip->name = StringSave(str);
1308         GetTitle(FeatureDescription, str, sizeof(str));
1309         sfip->description = StringSave(str);
1310 
1311         SetStatus(bFeatureAdd, FALSE);
1312         SetStatus(bFeatureEdit, FALSE);
1313         SetStatus(bFeatureMove, FALSE);
1314 
1315         parsSpecial = NULL;
1316         SetTitle(FeatureTitle, "name?");
1317         SetTitle(FeatureDescription, "");
1318     }
1319 
1320     UpdateEditFeatureList();
1321     SafeSetValue(Cn3D_lFeaturesEdited, iEditedFeature);
1322     ResetModelCtrls();
1323 
1324     /* set show/hide of each feature depending on selection status */
1325     Cn3D_SyncMenuHighlightWithOnOff();
1326     sfpThis = sfpGlobal;
1327     while (sfpThis) {
1328 #ifdef _DEBUG
1329         /* to verify that sfp's are always numbered consecutively (from 1) - many
1330            functions depend on this (and many can change it) */
1331         iCount++;
1332         if (iCount != sfpThis->choice)
1333             Message(MSG_POST, "internal error: discontinuity in sfp id: #%i has choice %i",
1334                 iCount, sfpThis->choice);
1335 #endif
1336         sfip = sfpThis->data.ptrvalue;
1337         pvnLoc = GetFeatureLocationForModel(sfip, pmsdThis);
1338         if (pvnLoc)
1339             Cn3DApplyUserDefinedFeatureToMGD(pmsdThis, pvnLoc, sfpThis->choice, sfip);
1340         pdnmsSlave = pmsdThis->pdnmsSlaves;
1341         while (pdnmsSlave) {
1342             PMSD pmsdSlave = (PMSD) pdnmsSlave->data.ptrvalue;
1343             pvnLoc = GetFeatureLocationForModel(sfip, pmsdSlave);
1344             if (pvnLoc)
1345                 Cn3DApplyUserDefinedFeatureToMGD(pmsdSlave, pvnLoc, sfpThis->choice, sfip);
1346             pdnmsSlave = pdnmsSlave->next;
1347         }
1348         sfpThis = sfpThis->next;
1349     }
1350 
1351     fnCn3D_RedrawWrapper(FALSE);
1352 }
1353 
1354 
1355 /*---------------------------------------------------------*/
1356 GrouP LIBCALL ModelControls(Nlm_GrouP prnt)
1357 {
1358     GrouP g, h1, h2, h3, h4;
1359     GrouP h5, h6, h7;
1360     Int2 k = 0;
1361     PrompT ppt[10], ppt0[10];
1362     PrompT ppt1, ppt2, ppt3, ppt4, ppt5, ppt6, ppt7, ppt8, ppt9, ppt10,
1363         ppt11;
1364     PrompT ppt12, ppt13, ppt14;
1365     RecT pptPos, btnPos;
1366     Int2 delta = 0;
1367 
1368     g = HiddenGroup(prnt, -1, 0, NULL);
1369     if (!g)
1370         return NULL;
1371     SetGroupSpacing(g, 3, 9);
1372 #ifdef WIN_MOTIF
1373     SetGroupMargins(g, 4, 1);
1374     SetGroupSpacing(g, 2, 1);
1375 #else
1376     SetGroupMargins(g, 1, 1);
1377     SetGroupSpacing(g, 0, 0);
1378 #endif
1379 
1380     h5 = HiddenGroup(g, 0, -3, NULL);
1381     SetGroupSpacing(h5, 20, 3);
1382     ppt12 =
1383         StaticPrompt(h5,
1384                      "Define Annotations: Use Mouse to Select Residues First",
1385                      0, stdLineHeight + 5, systemFont, 'c');
1386     h2 = HiddenGroup(h5, 0, -1, NULL);
1387     SetGroupSpacing(h2, 5, 3);
1388     StaticPrompt(h2, "    Name             ", 0, stdLineHeight + 5,
1389                  systemFont, 'c');
1390     FeatureTitle = DialogText(h2, "", 10, FeatureTitleProc);
1391     SetTitle(FeatureTitle, "name?");
1392 
1393     h3 = HiddenGroup(h5, 0, -1, NULL);
1394     SetGroupSpacing(h3, 5, 3);
1395     StaticPrompt(h3, "    Description ", 0, stdLineHeight + 5, systemFont,
1396                  'c');
1397     FeatureDescription = DialogText(h3, "", 20, NULL);
1398     AlignObjects(ALIGN_LEFT, (HANDLE) ppt12, (HANDLE) h2, (HANDLE) h3,
1399                  NULL);
1400     AlignObjects(ALIGN_LEFT, (HANDLE) h2, (HANDLE) h3, NULL);
1401 
1402 /*StaticPrompt(g, "         ",0, stdLineHeight + 5, systemFont, 'l'); */
1403     h1 = HiddenGroup(g, 0, -5, NULL);
1404     SetGroupSpacing(h1, 5, 3);
1405 
1406     Cn3D_lModelOnOffItem[0] = NULL; /* Cn3D_pupModelPBB includes off setting */
1407     Cn3D_lModelOnOffItem[1] = NULL; /* Cn3D_pupModelNABB includes off setting */
1408 
1409     ppt1 =
1410         StaticPrompt(h1, "    Set Style", 0, stdLineHeight + 5,
1411                      systemFont, 'c');
1412     ppt[0] =
1413         StaticPrompt(h1, "  Protein Backbone", 0, popupMenuHeight,
1414                      systemFont, 'l');
1415     ppt[1] =
1416         StaticPrompt(h1, "  Nucleotide Backbone", 0, popupMenuHeight,
1417                      systemFont, 'l');
1418     ppt[2] =
1419         StaticPrompt(h1, "  Protein Sidechains", 0, popupMenuHeight,
1420                      systemFont, 'l');
1421     ppt[3] =
1422         StaticPrompt(h1, "  Nucleotide Sidechains", 0, popupMenuHeight,
1423                      systemFont, 'l');
1424 /*AlignObjects (ALIGN_CENTER, (HANDLE) ppt1, (HANDLE) ppt [1], NULL); */
1425 
1426     ppt2 =
1427         StaticPrompt(h1, "On/Off", 0, stdLineHeight + 5, systemFont, 'c');
1428     Cn3D_pupModelPBB = PopupList(h1, FALSE, ModelPopupOnOffProc);
1429     PopupItem(Cn3D_pupModelPBB, "alpha C trace");
1430     PopupItem(Cn3D_pupModelPBB, "partial atom");
1431     PopupItem(Cn3D_pupModelPBB, "all atoms");
1432     PopupItem(Cn3D_pupModelPBB, "none");
1433     SafeSetValue(Cn3D_pupModelPBB, 1);
1434     Cn3D_pupModelNABB = PopupList(h1, FALSE, ModelPopupOnOffProc);
1435     PopupItem(Cn3D_pupModelNABB, "P trace");
1436     PopupItem(Cn3D_pupModelNABB, "partial atom");
1437     PopupItem(Cn3D_pupModelNABB, "all atoms");
1438     PopupItem(Cn3D_pupModelNABB, "none");
1439     SafeSetValue(Cn3D_pupModelNABB, 3);
1440 
1441     for (k = 2; k < 4; k++) {
1442         Cn3D_lModelOnOffItem[k] = CheckBox(h1, "", ModelButtonOnOffProc);
1443     }
1444     SafeSetStatus(Cn3D_lModelOnOffItem[3], TRUE);
1445     for (k = 2; k < 4; k++) {
1446         GetPosition(Cn3D_lModelOnOffItem[k], &btnPos);
1447         GetPosition(ppt[k], &pptPos);
1448         delta =
1449             (pptPos.bottom + pptPos.top) / 2 - (btnPos.bottom +
1450                                                 btnPos.top) / 2;
1451         if (delta != 0) {
1452             OffsetRect(&btnPos, 0, delta);
1453             SetPosition(Cn3D_lModelOnOffItem[k], &btnPos);
1454             AdjustPrnt((Nlm_GraphiC) Cn3D_lModelOnOffItem[k], &btnPos,
1455                        FALSE);
1456         }
1457     }
1458     AlignObjects(ALIGN_CENTER, (HANDLE) ppt2, (HANDLE) Cn3D_pupModelPBB,
1459                  (HANDLE) Cn3D_lModelOnOffItem[2],
1460                  (HANDLE) Cn3D_lModelOnOffItem[3], NULL);
1461 
1462     ppt3 =
1463         StaticPrompt(h1, "Drawing Style", 0, stdLineHeight + 5, systemFont, 'c');
1464     for (k = 0; k < 4; k++) {
1465         Cn3D_pupModelRenderStyle[k] = ModelRenderStyle(h1, k);
1466     }
1467     AlignObjects(ALIGN_CENTER, (HANDLE) ppt3,
1468                  (HANDLE) Cn3D_pupModelRenderStyle[0], NULL);
1469 
1470     ppt4 =
1471         StaticPrompt(h1, "Color", 0, stdLineHeight + 5, systemFont, 'c');
1472     for (k = 0; k < 4; k++) {
1473         Cn3D_pupModelColorStyle[k] = ModelColorStyle(h1, k);
1474     }
1475     AlignObjects(ALIGN_CENTER, (HANDLE) ppt4,
1476                  (HANDLE) Cn3D_pupModelColorStyle[0], NULL);
1477 
1478 /*StaticPrompt(g, "",0,0,Nlm_systemFont,'l'); */
1479 
1480     h4 = HiddenGroup(g, 0, -3, NULL);
1481     SetGroupSpacing(h4, 5, 3);
1482 
1483     ppt5 =
1484         StaticPrompt(h4, "    Set Label", 0, stdLineHeight + 5, systemFont,
1485                      'c');
1486     ppt0[0] =
1487         StaticPrompt(h4, "  Amino Acid", 0, popupMenuHeight, systemFont,
1488                      'l');
1489     ppt0[1] =
1490         StaticPrompt(h4, "  Nucleic Acid", 0, popupMenuHeight, systemFont,
1491                      'l');
1492 /*AlignObjects (ALIGN_CENTER, (HANDLE) ppt5, (HANDLE) ppt0 [1], NULL);  */
1493 
1494     ppt6 =
1495         StaticPrompt(h4, "On/Off", 0, stdLineHeight + 5, systemFont, 'c');
1496     Cn3D_pupLabelAA = PopupList(h4, FALSE, ModelLabelPopupOnOffProc);
1497     PopupItem(Cn3D_pupLabelAA, "none");
1498     PopupItem(Cn3D_pupLabelAA, "every AA");
1499     PopupItem(Cn3D_pupLabelAA, "every 5");
1500     PopupItem(Cn3D_pupLabelAA, "every 10");
1501     PopupItem(Cn3D_pupLabelAA, "every 20");
1502     PopupItem(Cn3D_pupLabelAA, "every 50");
1503     Cn3D_pupLabelNT = PopupList(h4, FALSE, ModelLabelPopupOnOffProc);
1504     PopupItem(Cn3D_pupLabelNT, "none");
1505     PopupItem(Cn3D_pupLabelNT, "every NA");
1506     PopupItem(Cn3D_pupLabelNT, "every 5");
1507     PopupItem(Cn3D_pupLabelNT, "every 10");
1508     PopupItem(Cn3D_pupLabelNT, "every 20");
1509     PopupItem(Cn3D_pupLabelNT, "every 50");
1510     AlignObjects(ALIGN_CENTER, (HANDLE) ppt6, (HANDLE) Cn3D_pupLabelAA,
1511                  (HANDLE) Cn3D_pupLabelNT, NULL);
1512 
1513     ppt7 = StaticPrompt(h4, "Name", 0, stdLineHeight + 5, systemFont, 'c');
1514     for (k = 0; k < 2; k++) {
1515         Cn3D_bLName[k] = PopupList(h4, FALSE, ModelLabelPopupOnOffProc);
1516         PopupItem(Cn3D_bLName[k], "none");
1517         PopupItem(Cn3D_bLName[k], "3 letter");
1518         PopupItem(Cn3D_bLName[k], "1 letter");
1519         PopupItem(Cn3D_bLName[k], "PDB");
1520     }
1521     AlignObjects(ALIGN_CENTER, (HANDLE) ppt7, (HANDLE) Cn3D_bLName[0],
1522                  (HANDLE) Cn3D_bLName[1], NULL);
1523 
1524     ppt8 = StaticPrompt(h4, "Num", 0, stdLineHeight + 5, systemFont, 'c');
1525     for (k = 0; k < 2; k++) {
1526         Cn3D_bLNum[k] = CheckBox(h4, "", ModelLabelButtonOnOffProc);
1527     }
1528     for (k = 0; k < 2; k++) {
1529         GetPosition(Cn3D_bLNum[k], &btnPos);
1530         GetPosition(ppt0[k], &pptPos);
1531         delta =
1532             (pptPos.bottom + pptPos.top) / 2 - (btnPos.bottom +
1533                                                 btnPos.top) / 2;
1534         if (delta != 0) {
1535             OffsetRect(&btnPos, 0, delta);
1536             SetPosition(Cn3D_bLNum[k], &btnPos);
1537             AdjustPrnt((Nlm_GraphiC) Cn3D_bLNum[k], &btnPos, FALSE);
1538         }
1539     }
1540     AlignObjects(ALIGN_CENTER, (HANDLE) ppt8, (HANDLE) Cn3D_bLNum[0],
1541                  (HANDLE) Cn3D_bLNum[1], NULL);
1542 
1543 #ifndef _OPENGL
1544     ppt9 =
1545         StaticPrompt(h4, "On Top", 0, stdLineHeight + 5, systemFont, 'c');
1546     for (k = 0; k < 2; k++) {
1547         Cn3D_bLTop[k] = CheckBox(h4, "", ModelLabelButtonOnOffProc);
1548     }
1549     for (k = 0; k < 2; k++) {
1550         GetPosition(Cn3D_bLTop[k], &btnPos);
1551         GetPosition(ppt0[k], &pptPos);
1552         delta =
1553             (pptPos.bottom + pptPos.top) / 2 - (btnPos.bottom +
1554                                                 btnPos.top) / 2;
1555         if (delta != 0) {
1556             OffsetRect(&btnPos, 0, delta);
1557             SetPosition(Cn3D_bLTop[k], &btnPos);
1558             AdjustPrnt((Nlm_GraphiC) Cn3D_bLTop[k], &btnPos, FALSE);
1559         }
1560     }
1561     AlignObjects(ALIGN_CENTER, (HANDLE) ppt9, (HANDLE) Cn3D_bLTop[0],
1562                  (HANDLE) Cn3D_bLTop[1], NULL);
1563 #endif
1564 
1565     ppt10 =
1566         StaticPrompt(h4, "White", 0, stdLineHeight + 5, systemFont, 'c');
1567     for (k = 0; k < 2; k++) {
1568         Cn3D_bLWhite[k] = CheckBox(h4, "", ModelLabelButtonOnOffProc);
1569     }
1570     for (k = 0; k < 2; k++) {
1571         GetPosition(Cn3D_bLWhite[k], &btnPos);
1572         GetPosition(ppt0[k], &pptPos);
1573         delta =
1574             (pptPos.bottom + pptPos.top) / 2 - (btnPos.bottom +
1575                                                 btnPos.top) / 2;
1576         if (delta != 0) {
1577             OffsetRect(&btnPos, 0, delta);
1578             SetPosition(Cn3D_bLWhite[k], &btnPos);
1579             AdjustPrnt((Nlm_GraphiC) Cn3D_bLWhite[k], &btnPos, FALSE);
1580         }
1581     }
1582     AlignObjects(ALIGN_CENTER, (HANDLE) ppt10, (HANDLE) Cn3D_bLWhite[0],
1583                  (HANDLE) Cn3D_bLWhite[1], NULL);
1584 
1585 #ifndef _OPENGL
1586     ppt11 =
1587         StaticPrompt(h4, "Size", 0, stdLineHeight + 5, systemFont, 'c');
1588     for (k = 0; k < 2; k++) {
1589         Cn3D_pupLabelSize[k] =
1590             PopupList(h4, FALSE, ModelLabelPopupOnOffProc);
1591         PopupItem(Cn3D_pupLabelSize[k], "1");
1592         PopupItem(Cn3D_pupLabelSize[k], "2");
1593         PopupItem(Cn3D_pupLabelSize[k], "3");
1594         PopupItem(Cn3D_pupLabelSize[k], "4");
1595         PopupItem(Cn3D_pupLabelSize[k], "5");
1596         PopupItem(Cn3D_pupLabelSize[k], "6");
1597         PopupItem(Cn3D_pupLabelSize[k], "7");
1598         PopupItem(Cn3D_pupLabelSize[k], "8");
1599         PopupItem(Cn3D_pupLabelSize[k], "9");
1600         PopupItem(Cn3D_pupLabelSize[k], "10");
1601     }
1602     AlignObjects(ALIGN_CENTER, (HANDLE) ppt11,
1603                  (HANDLE) Cn3D_pupLabelSize[0],
1604                  (HANDLE) Cn3D_pupLabelSize[1], NULL);
1605 #endif /* ndef _OPENGL */
1606 
1607     StaticPrompt(g, "", 0, 0, Nlm_systemFont, 'l');
1608 
1609     h7 = HiddenGroup(g, 0, -2, NULL);
1610     ppt13 =
1611         StaticPrompt(h7, " Edit Annotation:", 0, stdLineHeight + 5,
1612                      systemFont, 'c');
1613 
1614     h6 = HiddenGroup(h7, 0, -2, NULL);
1615     StaticPrompt(h6, "   ", 0, 0, Nlm_systemFont, 'l');
1616     StaticPrompt(h6, "   ", 0, 0, Nlm_systemFont, 'l');
1617 
1618     Cn3D_lFeaturesEdited = SingleList(h6, 5, 3, lFeatureEditedAction);
1619     StaticPrompt(h6, "", 0, 0, Nlm_systemFont, 'l');
1620 
1621     bFeatureAdd = CheckBox(h6, "Add", bFeatureAddAction);
1622     bFeatureDelete = CheckBox(h6, "Delete", bFeatureDeleteAction);
1623     bFeatureEdit = CheckBox(h6, "Edit", bFeatureEditAction);
1624     bFeatureMove = CheckBox(h6, "Move", bFeatureMoveAction);
1625 
1626     ppt14 =
1627         StaticPrompt(h7, " Display Annotation:", 0, stdLineHeight + 5,
1628                      systemFont, 'c');
1629     Cn3D_lFeaturesOnOff = MultiList(h7, 5, 3, Cn3D_FeatureOnOffProc);
1630     AlignObjects(ALIGN_CENTER, (HANDLE) g, (HANDLE) ppt14,
1631                  (HANDLE) Cn3D_lFeaturesOnOff, NULL);
1632 
1633     Cn3D_bModelApply = PushButton(g, "Apply!", Cn3D_FeatureApplyProc);
1634 
1635     AlignObjects(ALIGN_CENTER, (HANDLE) Cn3D_bModelApply, (HANDLE) h1,
1636                  NULL);
1637 
1638     ModelResetLabelCtrls();
1639     ResetModelCtrls();
1640     return g;
1641 }
1642 
1643 /*---------------------------------------------------------*/
1644 void LIBCALL ResetModelCtrls(void)
1645 {
1646     /* this function may not be neccessary */
1647     Int2 k = 0;
1648     PARS pars = NULL;;
1649 
1650     pars = GetSpecialAlgorRenderSet();
1651     if (!pars) {
1652         SafeSetValue(Cn3D_pupModelPBB, 1);
1653         SafeSetValue(Cn3D_pupModelNABB, 1);
1654 
1655         for (k = 2; k < 4; k++) {
1656             SetItemStatus(Cn3D_lModelOnOffItem[k], 1, FALSE);
1657         }
1658 
1659         SafeSetValue(Cn3D_pupModelPBB, 4);
1660         SafeSetValue(Cn3D_pupModelNABB, 4);
1661 
1662         for (k = 0; k < 4; k++) {
1663             SafeSetValue(Cn3D_pupModelRenderStyle[k], 1);
1664             SafeSetValue(Cn3D_pupModelColorStyle[k], 1);
1665         }
1666     }
1667     return;
1668 }
1669 
1670 /*-------------------------------------------*/
1671 static BiostrucFeatureSetDescrPtr MakeDescrForUserDefinedFeature(SpecialFeaturePtr
1672                                                          sfpThis)
1673 {
1674     ValNodePtr descr = NULL, descr_head = NULL, descr_tail = NULL;
1675     SpecialFeatureInfoPtr sfipThis = NULL;
1676 
1677     if (!sfpThis)
1678         return NULL;
1679     sfipThis = sfpThis->data.ptrvalue;
1680     if (!sfipThis)
1681         return NULL;
1682 
1683     descr = ValNodeNew(NULL);
1684     descr->choice = 1;
1685     descr->data.ptrvalue = StringSave("User Defined Features");
1686 
1687     descr_head = descr;
1688     descr_tail = descr;
1689 
1690     if (sfipThis->description) {
1691         descr = ValNodeNew(NULL);
1692         descr->choice = 3;
1693         descr->data.ptrvalue = StringSave(sfipThis->description);
1694         descr_tail->next = descr;
1695         descr_tail = descr;
1696     }
1697 
1698     if (sfipThis->isOn) {
1699         descr = ValNodeNew(NULL);
1700         descr->choice = 3;
1701         descr->data.ptrvalue = StringSave("On");
1702         descr_tail->next = descr;
1703         descr_tail = descr;
1704     }
1705 
1706     return descr_head;
1707 }
1708 
1709 /*-------------------------------------------*/
1710 static ValNodePtr GetBiostrucFeatureLocationForHihglightedResidues(PDNMS pdnmsThis,
1711                                                            Int2 iFeature)
1712 {
1713 
1714     PMSD pmsdThis = NULL;
1715     PDNMM pdnmmHead = NULL;
1716     PMMD pmmdThis = NULL;
1717     PDNMG pdnmgThis = NULL;
1718     PMGD pmgdThis = NULL;
1719 
1720     ResidueIntervalPntrPtr rsip = NULL, rsip_head = NULL, rsip_tail = NULL;
1721     ValNodePtr rsp = NULL;      /* ResiduePntrsPtr */
1722     ChemGraphPntrsPtr pcgpThis = NULL;
1723     ValNodePtr llp = NULL;
1724 
1725     Int2 iMol = 0, iMolCurrent = 0;
1726     Int4 from = 0, to = 0;
1727 
1728     Boolean Started = FALSE, SingleInterval, UserDefinedFeatureFound =
1729         FALSE;
1730     Boolean UserDefinedFeatureFoundInThisMolecule = FALSE;
1731 
1732     pmsdThis = pdnmsThis->data.ptrvalue;
1733     pdnmmHead = pmsdThis->pdnmmHead;
1734     iMol = 0;
1735     while (pdnmmHead) {
1736         pmmdThis = pdnmmHead->data.ptrvalue;
1737         if (pmmdThis->bWhat != (Byte) AM_PROT
1738             && pmmdThis->bWhat != (Byte) AM_RNA
1739             && pmmdThis->bWhat != (Byte) AM_DNA)
1740             goto setout1;
1741         Started = FALSE;
1742         UserDefinedFeatureFoundInThisMolecule = FALSE;
1743         SingleInterval = TRUE;
1744 
1745         for (pdnmgThis = pmmdThis->pdnmgHead; pdnmgThis != NULL;
1746              pdnmgThis = pdnmgThis->next) {
1747             pmgdThis = (PMGD) pdnmgThis->data.ptrvalue;
1748             if (pmgdThis->bHighlighted) {
1749                 UserDefinedFeatureFound = TRUE;
1750                 iMolCurrent = iMol + 1;
1751                 if (!Started) {
1752                     from = pdnmgThis->choice;
1753                     to = pdnmgThis->choice;
1754                     Started = TRUE;
1755                     UserDefinedFeatureFoundInThisMolecule = TRUE;
1756                 } else {
1757                     if ((pdnmgThis->choice - to) == 1) {
1758                         to = pdnmgThis->choice;
1759                     } else {
1760                         SingleInterval = FALSE;
1761                         rsip = ResidueIntervalPntrNew();
1762                         rsip->molecule_id = pmmdThis->iChainId;
1763                         rsip->from = from;
1764                         rsip->to = to;
1765                         if (!rsip_head) {
1766                             rsip_head = rsip;
1767                             rsip_tail = rsip;
1768                         } else {
1769                             rsip_tail->next = rsip;
1770                             rsip_tail = rsip;
1771                         }
1772 
1773                         from = pdnmgThis->choice;
1774                         to = pdnmgThis->choice;
1775                         iMolCurrent = iMol + 1;
1776                     }
1777                 }
1778             }
1779         }
1780         if (UserDefinedFeatureFoundInThisMolecule) {
1781             rsip = ResidueIntervalPntrNew();
1782             rsip->molecule_id = pmmdThis->iChainId;
1783             rsip->from = from;
1784             rsip->to = to;
1785             if (!rsip_head) {
1786                 rsip_head = rsip;
1787                 rsip_tail = rsip;
1788             } else {
1789                 rsip_tail->next = rsip;
1790                 rsip_tail = rsip;
1791             }                   /* for either last region or single region */
1792         }
1793 
1794         iMol++;
1795       setout1:
1796         pdnmmHead = pdnmmHead->next;
1797     }
1798 
1799     if (!UserDefinedFeatureFound)
1800         return NULL;
1801 
1802     rsp = ValNodeNew(NULL);
1803     rsp->choice = ResiduePntrs_interval;
1804     rsp->data.ptrvalue = rsip_head;
1805 
1806     pcgpThis = ValNodeNew(NULL);
1807     pcgpThis->choice = ChemGraphPntrs_residues;
1808     pcgpThis->data.ptrvalue = rsp;
1809 
1810     llp = ValNodeNew(NULL);
1811     llp->choice = Location_location_subgraph;
1812     llp->data.ptrvalue = pcgpThis;
1813 
1814     return llp;
1815 }
1816 
1817 /*-------------------------------------------*/
1818 static UserFieldPtr FillUserObjectField(UserFieldPtr ufp, ObjectIdPtr oip)
1819 {
1820     ufp->choice = 1;
1821     ufp->label = oip;
1822     return ufp;
1823 }
1824 
1825 /*-------------------------------------------*/
1826 static UserObjectPtr MakeUserObjectForUserDefinedFeature(PARS pars)
1827 {
1828     UserObjectPtr ubp = NULL;
1829     UserFieldPtr head_ufp = NULL, curr_ufp = NULL, tail_ufp = NULL;
1830     ObjectIdPtr oip = NULL;
1831     Char str[20];
1832     Uint1Ptr rgb = NULL;
1833 
1834     head_ufp = UserFieldNew();
1835     oip = ObjectIdNew();
1836     oip->str = StringSave("Protein Backbone Representative");
1837     FillUserObjectField(head_ufp, oip);
1838 
1839     if (pars->PVirtualBBOn)
1840         head_ufp->data.ptrvalue = StringSave("Alpha C Trace");
1841     else if (pars->PPartialBBOn)
1842         head_ufp->data.ptrvalue = StringSave("partial atom");
1843     else if (pars->PCompleteBBOn)
1844         head_ufp->data.ptrvalue = StringSave("all atoms");
1845     else
1846         head_ufp->data.ptrvalue = StringSave("none");
1847 
1848     curr_ufp = head_ufp;
1849 
1850     tail_ufp = UserFieldNew();
1851     oip = ObjectIdNew();
1852     oip->str = StringSave("Protein Backbone Render");
1853     FillUserObjectField(tail_ufp, oip);
1854     if (pars->PBBRender == R_WIRE)
1855         tail_ufp->data.ptrvalue = StringSave("Wire Frame");
1856     else if (pars->PBBRender == R_STICK)
1857         tail_ufp->data.ptrvalue = StringSave("Tubes");
1858     else if (pars->PBBRender == R_BALLNSTICK)
1859         tail_ufp->data.ptrvalue = StringSave("Ball & Stick");
1860     else if (pars->PBBRender == R_THICKWIRE)
1861         tail_ufp->data.ptrvalue = StringSave("Fat Tubes");
1862     else if (pars->PBBRender == R_SPACE)
1863         tail_ufp->data.ptrvalue = StringSave("Space Fill");
1864 
1865     curr_ufp->next = tail_ufp;
1866     curr_ufp = tail_ufp;
1867 
1868     tail_ufp = UserFieldNew();
1869     oip = ObjectIdNew();
1870     oip->str = StringSave("Protein Backbone Color");
1871     FillUserObjectField(tail_ufp, oip);
1872     rgb = pars->PBBColRGB;
1873     sprintf(str, "%d %d %d", *rgb, *(rgb + 1), *(rgb + 2));
1874     tail_ufp->data.ptrvalue = StringSave(str);
1875 
1876     curr_ufp->next = tail_ufp;
1877     curr_ufp = tail_ufp;
1878 
1879     tail_ufp = UserFieldNew();
1880     oip = ObjectIdNew();
1881     oip->str = StringSave("Protein Side Chain Status");
1882     FillUserObjectField(tail_ufp, oip);
1883     if (pars->PResiduesOn)
1884         tail_ufp->data.ptrvalue = StringSave("On");
1885     else
1886         tail_ufp->data.ptrvalue = StringSave("Off");
1887 
1888     curr_ufp->next = tail_ufp;
1889     curr_ufp = tail_ufp;
1890 
1891     tail_ufp = UserFieldNew();
1892     oip = ObjectIdNew();
1893     oip->str = StringSave("Protein Side Chain Render");
1894     FillUserObjectField(tail_ufp, oip);
1895     if (pars->PResRender == R_WIRE)
1896         tail_ufp->data.ptrvalue = StringSave("Wire Frame");
1897     else if (pars->PResRender == R_STICK)
1898         tail_ufp->data.ptrvalue = StringSave("Tubes");
1899     else if (pars->PResRender == R_BALLNSTICK)
1900         tail_ufp->data.ptrvalue = StringSave("Ball & Stick");
1901     else if (pars->PResRender == R_THICKWIRE)
1902         tail_ufp->data.ptrvalue = StringSave("Fat Tubes");
1903     else if (pars->PResRender == R_SPACE)
1904         tail_ufp->data.ptrvalue = StringSave("Space Fill");
1905 
1906     curr_ufp->next = tail_ufp;
1907     curr_ufp = tail_ufp;
1908 
1909     tail_ufp = UserFieldNew();
1910     oip = ObjectIdNew();
1911     oip->str = StringSave("Protein Side Chain Color");
1912     FillUserObjectField(tail_ufp, oip);
1913     rgb = pars->PResColRGB;
1914     sprintf(str, "%d %d %d", *rgb, *(rgb + 1), *(rgb + 2));
1915     tail_ufp->data.ptrvalue = StringSave(str);
1916 
1917     curr_ufp->next = tail_ufp;
1918     curr_ufp = tail_ufp;
1919 
1920     tail_ufp = UserFieldNew();
1921     oip = ObjectIdNew();
1922     oip->str = StringSave("Protein Label Status");
1923     FillUserObjectField(tail_ufp, oip);
1924     sprintf(str, "%d", (Uint1) pars->PBBLabelInterval);
1925     tail_ufp->data.ptrvalue = StringSave(str);
1926 
1927     curr_ufp->next = tail_ufp;
1928     curr_ufp = tail_ufp;
1929 
1930     tail_ufp = UserFieldNew();
1931     oip = ObjectIdNew();
1932     oip->str = StringSave("Protein Label Just");
1933     FillUserObjectField(tail_ufp, oip);
1934     sprintf(str, "%d", (Uint1) pars->PBBLabelJust);
1935     tail_ufp->data.ptrvalue = StringSave(str);
1936 
1937     curr_ufp->next = tail_ufp;
1938     curr_ufp = tail_ufp;
1939 
1940     tail_ufp = UserFieldNew();
1941     oip = ObjectIdNew();
1942     oip->str = StringSave("Protein Label Scale");
1943     FillUserObjectField(tail_ufp, oip);
1944     sprintf(str, "%d", (Uint1) pars->PBBLabelScale);
1945     tail_ufp->data.ptrvalue = StringSave(str);
1946 
1947     curr_ufp->next = tail_ufp;
1948     curr_ufp = tail_ufp;
1949 
1950     tail_ufp = UserFieldNew();
1951     oip = ObjectIdNew();
1952     oip->str = StringSave("Protein Label Style");
1953     FillUserObjectField(tail_ufp, oip);
1954     sprintf(str, "%d", (Uint1) pars->PBBLabelStyle);
1955     tail_ufp->data.ptrvalue = StringSave(str);
1956 
1957     curr_ufp->next = tail_ufp;
1958     curr_ufp = tail_ufp;
1959 
1960     tail_ufp = UserFieldNew();
1961     oip = ObjectIdNew();
1962     oip->str = StringSave("Nucleic Acid Backbone Representative");
1963     FillUserObjectField(tail_ufp, oip);
1964 
1965     if (pars->NTVirtualBBOn)
1966         tail_ufp->data.ptrvalue = StringSave("Alpha C Trace");
1967     else if (pars->NTPartialBBOn)
1968         tail_ufp->data.ptrvalue = StringSave("partial atom");
1969     else if (pars->NTCompleteBBOn)
1970         tail_ufp->data.ptrvalue = StringSave("all atoms");
1971     else
1972         tail_ufp->data.ptrvalue = StringSave("none");
1973 
1974     curr_ufp->next = tail_ufp;
1975     curr_ufp = tail_ufp;
1976 
1977     tail_ufp = UserFieldNew();
1978     oip = ObjectIdNew();
1979     oip->str = StringSave("Nucleic Acid Backbone Render");
1980     FillUserObjectField(tail_ufp, oip);
1981     if (pars->NTBBRender == R_WIRE)
1982         tail_ufp->data.ptrvalue = StringSave("Wire Frame");
1983     else if (pars->NTBBRender == R_STICK)
1984         tail_ufp->data.ptrvalue = StringSave("Tubes");
1985     else if (pars->NTBBRender == R_BALLNSTICK)
1986         tail_ufp->data.ptrvalue = StringSave("Ball & Stick");
1987     else if (pars->NTBBRender == R_THICKWIRE)
1988         tail_ufp->data.ptrvalue = StringSave("Fat Tubes");
1989     else if (pars->NTBBRender == R_SPACE)
1990         tail_ufp->data.ptrvalue = StringSave("Space Fill");
1991 
1992     curr_ufp->next = tail_ufp;
1993     curr_ufp = tail_ufp;
1994 
1995     tail_ufp = UserFieldNew();
1996     oip = ObjectIdNew();
1997     oip->str = StringSave("Nucleic Acid Backbone Color");
1998     FillUserObjectField(tail_ufp, oip);
1999     rgb = pars->NTBBColRGB;
2000     sprintf(str, "%d %d %d", *rgb, *(rgb + 1), *(rgb + 2));
2001     tail_ufp->data.ptrvalue = StringSave(str);
2002 
2003     curr_ufp->next = tail_ufp;
2004     curr_ufp = tail_ufp;
2005 
2006     tail_ufp = UserFieldNew();
2007     oip = ObjectIdNew();
2008     oip->str = StringSave("Nucleic Acid Side Chain Status");
2009     FillUserObjectField(tail_ufp, oip);
2010     if (pars->NTResiduesOn)
2011         tail_ufp->data.ptrvalue = StringSave("On");
2012     else
2013         tail_ufp->data.ptrvalue = StringSave("Off");
2014 
2015     curr_ufp->next = tail_ufp;
2016     curr_ufp = tail_ufp;
2017 
2018     tail_ufp = UserFieldNew();
2019     oip = ObjectIdNew();
2020     oip->str = StringSave("Nucleic Side Chain Render");
2021     FillUserObjectField(tail_ufp, oip);
2022     if (pars->NTResRender == R_WIRE)
2023         tail_ufp->data.ptrvalue = StringSave("Wire Frame");
2024     else if (pars->NTResRender == R_STICK)
2025         tail_ufp->data.ptrvalue = StringSave("Tubes");
2026     else if (pars->NTResRender == R_BALLNSTICK)
2027         tail_ufp->data.ptrvalue = StringSave("Ball & Stick");
2028     else if (pars->NTResRender == R_THICKWIRE)
2029         tail_ufp->data.ptrvalue = StringSave("Fat Tubes");
2030     else if (pars->NTResRender == R_SPACE)
2031         tail_ufp->data.ptrvalue = StringSave("Space Fill");
2032 
2033     curr_ufp->next = tail_ufp;
2034     curr_ufp = tail_ufp;
2035 
2036     tail_ufp = UserFieldNew();
2037     oip = ObjectIdNew();
2038     oip->str = StringSave("Nucleic Acid Side Chain Color");
2039     FillUserObjectField(tail_ufp, oip);
2040     rgb = pars->NTResColRGB;
2041     sprintf(str, "%d %d %d", *rgb, *(rgb + 1), *(rgb + 2));
2042     tail_ufp->data.ptrvalue = StringSave(str);
2043 
2044     curr_ufp->next = tail_ufp;
2045     curr_ufp = tail_ufp;
2046 
2047     tail_ufp = UserFieldNew();
2048     oip = ObjectIdNew();
2049     oip->str = StringSave("Nucleic Acid Label Status");
2050     FillUserObjectField(tail_ufp, oip);
2051     sprintf(str, "%d", (Uint1) pars->NTBBLabelInterval);
2052     tail_ufp->data.ptrvalue = StringSave(str);
2053 
2054     curr_ufp->next = tail_ufp;
2055     curr_ufp = tail_ufp;
2056 
2057     tail_ufp = UserFieldNew();
2058     oip = ObjectIdNew();
2059     oip->str = StringSave("Nucleic Acid Label Just");
2060     FillUserObjectField(tail_ufp, oip);
2061     sprintf(str, "%d", (Uint1) pars->NTBBLabelJust);
2062     tail_ufp->data.ptrvalue = StringSave(str);
2063 
2064     curr_ufp->next = tail_ufp;
2065     curr_ufp = tail_ufp;
2066 
2067     tail_ufp = UserFieldNew();
2068     oip = ObjectIdNew();
2069     oip->str = StringSave("Nucleic Acid Label Scale");
2070     FillUserObjectField(tail_ufp, oip);
2071     sprintf(str, "%d", (Uint1) pars->NTBBLabelScale);
2072     tail_ufp->data.ptrvalue = StringSave(str);
2073 
2074     curr_ufp->next = tail_ufp;
2075     curr_ufp = tail_ufp;
2076 
2077     tail_ufp = UserFieldNew();
2078     oip = ObjectIdNew();
2079     oip->str = StringSave("Nucleic Acid Label Style");
2080     FillUserObjectField(tail_ufp, oip);
2081     sprintf(str, "%d", (Uint1) pars->NTBBLabelStyle);
2082     tail_ufp->data.ptrvalue = StringSave(str);
2083 
2084     curr_ufp->next = tail_ufp;
2085     curr_ufp = tail_ufp;
2086     oip = ObjectIdNew();
2087     oip->str = StringSave("Cn3D Rendering");
2088 
2089     ubp = UserObjectNew();
2090     ubp->type = oip;
2091     ubp->data = head_ufp;
2092     ubp->_class = StringSave("Property for User Defined Feature");
2093 
2094     return (ubp);
2095 }
2096 
2097 /*-------------------------------------------*/
2098 static ValNodePtr
2099 MakeBiostrucFeaturePropertyForUserDefinedFeature(SpecialFeaturePtr sfpThis)
2100 {
2101     ValNodePtr ppp = NULL;
2102     SpecialFeatureInfoPtr sfipThis = NULL;
2103     PARS parsThis = NULL;
2104 
2105     sfipThis = sfpThis->data.ptrvalue;
2106     parsThis = sfipThis->parsSpecial;
2107 
2108     ppp = ValNodeNew(NULL);
2109     ppp->choice = 6;
2110     ppp->data.ptrvalue = MakeUserObjectForUserDefinedFeature(parsThis);
2111 
2112     return ppp;
2113 }
2114 
2115 /*-------------------------------------------*/
2116 static BiostrucFeatureSetPtr
2117 MakeBiostrucFeatureSetForUserDefinedFeature(PDNMS pdnmsThis,
2118                                             BiostrucPtr bsp,
2119                                             SpecialFeaturePtr sfpThis,
2120                                             Int2 iCount)
2121 {
2122     BiostrucFeatureSetPtr bsfsp = NULL, bsfsp_head = NULL, bsfsp_tail =
2123         NULL;
2124     BiostrucFeaturePtr bsfp = NULL;
2125     ValNodePtr pvnLoc;
2126     SpecialFeatureInfoPtr sfipThis = NULL;
2127 
2128     sfipThis = sfpThis->data.ptrvalue;
2129 
2130     pvnLoc = GetFeatureLocationForModel(sfipThis, (PMSD) pdnmsThis->data.ptrvalue);
2131     if (!pvnLoc) return NULL;
2132 
2133     bsfp = BiostrucFeatureNew();
2134     if (!bsfp) return NULL;
2135     bsfp->name = StringSave(sfipThis->name);
2136     bsfp->type = Feature_type_other;
2137     bsfp->Location_location = CopyLocation(pvnLoc);
2138 
2139     bsfp->Property_property =
2140         MakeBiostrucFeaturePropertyForUserDefinedFeature(sfpThis);
2141 
2142     bsfsp = BiostrucFeatureSetNew();
2143     bsfsp->id = iCount;
2144     bsfsp->descr = MakeDescrForUserDefinedFeature(sfpThis);
2145     bsfsp->features = bsfp;
2146     bsfsp->next = NULL;
2147 
2148     return bsfsp;
2149 }
2150 
2151 /*-------------------------------------------*/
2152 PDNMS Cn3DAddUserDefinedFeatureToBiostruc(PDNMS pdnmsThis)
2153 {
2154     BiostrucPtr bsp = NULL;
2155     PMSD pmsdThis = NULL;
2156     BiostrucFeatureSetPtr bsfsp = NULL, bsfsp_head = NULL, bsfsp_tail = NULL;
2157     SpecialFeaturePtr sfpThis = NULL;
2158     Int2 iCount;
2159 
2160     pmsdThis = pdnmsThis->data.ptrvalue;
2161     bsp = pmsdThis->pbsBS;
2162 
2163     sfpThis = sfpGlobal;
2164     iCount = 1;
2165     while (sfpThis) {
2166         bsfsp =
2167             MakeBiostrucFeatureSetForUserDefinedFeature(pdnmsThis, bsp,
2168                                                        sfpThis, iCount);
2169         if (bsfsp) {
2170             if (!bsfsp_head) {
2171                 bsfsp_head = bsfsp;
2172                 bsfsp_tail = bsfsp;
2173             } else {
2174                 bsfsp_tail->next = bsfsp;
2175                 bsfsp_tail = bsfsp;
2176             }
2177         }
2178 
2179         sfpThis = sfpThis->next;
2180         iCount++;
2181     }
2182 
2183     bsfsp = bsp->features;
2184     while (bsfsp->next) {
2185         bsfsp = bsfsp->next;
2186     }
2187     bsfsp->next = bsfsp_head;
2188 
2189     return pdnmsThis;
2190 }
2191 
2192 /*---------------------------------------*/
2193 static SpecialFeatureInfoPtr GetUserDefinedFeature(Int4 id)
2194 {
2195     SpecialFeaturePtr sfpThis = NULL;
2196     SpecialFeatureInfoPtr sfipThis = NULL;
2197 
2198     sfpThis = sfpThis_head;
2199     while (sfpThis) {
2200         if (sfpThis->choice == id) {
2201             return sfpThis->data.ptrvalue;
2202         }
2203         sfpThis = sfpThis->next;
2204     }
2205     return NULL;
2206 }
2207 
2208 /*-------------------------------------*/
2209 static void Cn3DApplyUserDefinedFeatureToMGD(PMSD pmsdThis, ValNodePtr llp,
2210                                       Int2 iFeature, SpecialFeatureInfoPtr sfip)
2211 {
2212     PDNMM pdnmmHead = NULL;
2213     PMMD pmmdThis = NULL;
2214     PDNMG pdnmgThis = NULL;
2215     PMGD pmgdThis = NULL;
2216     ChemGraphPntrsPtr pcgpThis = NULL;
2217     ValNodePtr rsp = NULL;
2218     ResidueIntervalPntrPtr rsip = NULL;
2219 
2220     pcgpThis = llp->data.ptrvalue;
2221     rsp = pcgpThis->data.ptrvalue;
2222     rsip = rsp->data.ptrvalue;
2223     while (rsip) {
2224         pdnmmHead = pmsdThis->pdnmmHead;
2225         while (pdnmmHead) {
2226             pmmdThis = pdnmmHead->data.ptrvalue;
2227             if (pmmdThis->bWhat != (Byte) AM_PROT
2228                 && pmmdThis->bWhat != (Byte) AM_RNA
2229                 && pmmdThis->bWhat != (Byte) AM_DNA)
2230                 goto setout1;
2231             if (rsip->molecule_id == pmmdThis->iChainId) {
2232                 for (pdnmgThis = pmmdThis->pdnmgHead; pdnmgThis != NULL;
2233                      pdnmgThis = pdnmgThis->next) {
2234                     if (pdnmgThis->choice >= rsip->from
2235                         && pdnmgThis->choice <= rsip->to) {
2236                         pmgdThis = (PMGD) pdnmgThis->data.ptrvalue;
2237                         if (sfip->isOn)
2238                             AddPARSToMGD(pmgdThis, iFeature, sfip->parsSpecial);
2239                         else
2240                             RemovePARSFromMGD((PFB) pmgdThis, 0, iFeature, NULL);
2241                     }
2242                 }
2243             }
2244           setout1:
2245             pdnmmHead = pdnmmHead->next;
2246         }
2247         rsip = rsip->next;
2248     }
2249 }
2250 
2251 /*-------------------------------------*/
2252 static PARS GetSpecialParsForUserDefinedFeature(UserObjectPtr ubp)
2253 {
2254 
2255     PARS pars = NULL;
2256     UserFieldPtr ufp = NULL;
2257     ObjectIdPtr oip = NULL;
2258     short rgb_short[3], num;
2259 
2260     pars = GetNewSpecialAlgorRenderSet();
2261 
2262     ufp = ubp->data;
2263     while (ufp) {
2264         oip = ufp->label;
2265         if (StringCmp(oip->str, "Protein Backbone Representative") == 0) {
2266             if (StringCmp(ufp->data.ptrvalue, "Alpha C Trace") == 0) {
2267                 pars->PVirtualBBOn = TRUE;
2268                 pars->PPartialBBOn = FALSE;
2269                 pars->PCompleteBBOn = FALSE;
2270             } else if (StringCmp(ufp->data.ptrvalue, "all atoms") == 0) {
2271                 pars->PPartialBBOn = FALSE;
2272                 pars->PVirtualBBOn = FALSE;
2273                 pars->PCompleteBBOn = TRUE;
2274             } else if (StringCmp(ufp->data.ptrvalue, "partial atom") == 0) {
2275                 pars->PCompleteBBOn = FALSE;
2276                 pars->PVirtualBBOn = FALSE;
2277                 pars->PPartialBBOn = TRUE;
2278             }
2279         } else if (StringCmp(oip->str, "Protein Backbone Render") == 0) {
2280             if (StringCmp(ufp->data.ptrvalue, "Wire Frame") == 0)
2281                 pars->PBBRender = R_WIRE;
2282             else if (StringCmp(ufp->data.ptrvalue, "Tubes") == 0)
2283                 pars->PBBRender = R_STICK;
2284             else if (StringCmp(ufp->data.ptrvalue, "Ball & Stick") == 0)
2285                 pars->PBBRender = R_BALLNSTICK;
2286             else if (StringCmp(ufp->data.ptrvalue, "Fat Tubes") == 0)
2287                 pars->PBBRender = R_THICKWIRE;
2288             else if (StringCmp(ufp->data.ptrvalue, "Space Fill") == 0)
2289                 pars->PBBRender = R_SPACE;
2290         } else if (StringCmp(oip->str, "Protein Backbone Color") == 0) {
2291             sscanf(ufp->data.ptrvalue, "%hd %hd %hd", &rgb_short[0],
2292                    &rgb_short[1], &rgb_short[2]);
2293             pars->PBBColRGB[0] = (Uint1) rgb_short[0];
2294             pars->PBBColRGB[1] = (Uint1) rgb_short[1];
2295             pars->PBBColRGB[2] = (Uint1) rgb_short[2];
2296             pars->PBBColor = C_BYCHOICE;
2297 
2298         } else if (StringCmp(oip->str, "Protein Side Chain Status") == 0) {
2299             if (StringCmp(ufp->data.ptrvalue, "On") == 0)
2300                 pars->PResiduesOn = TRUE;
2301             else
2302                 pars->PResiduesOn = FALSE;
2303         } else if (StringCmp(oip->str, "Protein Side Chain Render") == 0) {
2304             if (StringCmp(ufp->data.ptrvalue, "Wire Frame") == 0)
2305                 pars->PResRender = R_WIRE;
2306             else if (StringCmp(ufp->data.ptrvalue, "Tubes") == 0)
2307                 pars->PResRender = R_STICK;
2308             else if (StringCmp(ufp->data.ptrvalue, "Ball & Stick") == 0)
2309                 pars->PResRender = R_BALLNSTICK;
2310             else if (StringCmp(ufp->data.ptrvalue, "Fat Tubes") == 0)
2311                 pars->PResRender = R_THICKWIRE;
2312             else if (StringCmp(ufp->data.ptrvalue, "Space Fill") == 0)
2313                 pars->PResRender = R_SPACE;
2314         } else if (StringCmp(oip->str, "Protein Side Chain Color") == 0) {
2315             sscanf(ufp->data.ptrvalue, "%hd %hd %hd", &rgb_short[0],
2316                    &rgb_short[1], &rgb_short[2]);
2317             pars->PResColRGB[0] = (Uint1) rgb_short[0];
2318             pars->PResColRGB[1] = (Uint1) rgb_short[1];
2319             pars->PResColRGB[2] = (Uint1) rgb_short[2];
2320             pars->PResColor = C_BYCHOICE;
2321         } else if (StringCmp(oip->str, "Protein Label Status") == 0) {
2322             sscanf(ufp->data.ptrvalue, "%hd", &num);
2323             pars->PBBLabelInterval = (Uint1) num;
2324         } else if (StringCmp(oip->str, "Protein Label Just") == 0) {
2325             sscanf(ufp->data.ptrvalue, "%hd", &num);
2326             pars->PBBLabelJust = (Uint1) num;
2327         } else if (StringCmp(oip->str, "Protein Label Scale") == 0) {
2328             sscanf(ufp->data.ptrvalue, "%hd", &num);
2329             pars->PBBLabelScale = (Uint1) num;
2330         } else if (StringCmp(oip->str, "Protein Label Style") == 0) {
2331             sscanf(ufp->data.ptrvalue, "%hd", &num);
2332             pars->PBBLabelStyle = (Uint1) num;
2333         }
2334         if (StringCmp(oip->str, "Nucleic Acid Backbone Representative") ==
2335             0) {
2336             if (StringCmp(ufp->data.ptrvalue, "Alpha C Trace") == 0) {
2337                 pars->NTVirtualBBOn = TRUE;
2338                 pars->NTPartialBBOn = FALSE;
2339                 pars->NTCompleteBBOn = FALSE;
2340             } else if (StringCmp(ufp->data.ptrvalue, "all atoms") == 0) {
2341                 pars->NTPartialBBOn = FALSE;
2342                 pars->NTVirtualBBOn = FALSE;
2343                 pars->NTCompleteBBOn = TRUE;
2344             } else if (StringCmp(ufp->data.ptrvalue, "partial atom") == 0) {
2345                 pars->NTCompleteBBOn = FALSE;
2346                 pars->NTVirtualBBOn = FALSE;
2347                 pars->NTPartialBBOn = TRUE;
2348             }
2349         }
2350             else if (StringCmp(oip->str, "Nucleic Acid Backbone Render") ==
2351                      0) {
2352             if (StringCmp(ufp->data.ptrvalue, "Wire Frame") == 0)
2353                 pars->NTBBRender = R_WIRE;
2354             else if (StringCmp(ufp->data.ptrvalue, "Tubes") == 0)
2355                 pars->NTBBRender = R_STICK;
2356             else if (StringCmp(ufp->data.ptrvalue, "Ball & Stick") == 0)
2357                 pars->NTBBRender = R_BALLNSTICK;
2358             else if (StringCmp(ufp->data.ptrvalue, "Fat Tubes") == 0)
2359                 pars->NTBBRender = R_THICKWIRE;
2360             else if (StringCmp(ufp->data.ptrvalue, "Space Fill") == 0)
2361                 pars->NTBBRender = R_SPACE;
2362         } else if (StringCmp(oip->str, "Nucleic Acid Backbone Color") == 0) {
2363             sscanf(ufp->data.ptrvalue, "%hd %hd %hd", &rgb_short[0],
2364                    &rgb_short[1], &rgb_short[2]);
2365             pars->NTBBColRGB[0] = (Uint1) rgb_short[0];
2366             pars->NTBBColRGB[1] = (Uint1) rgb_short[1];
2367             pars->NTBBColRGB[2] = (Uint1) rgb_short[2];
2368             pars->NTBBColor = C_BYCHOICE;
2369         }
2370             else if (StringCmp(oip->str, "Nucleic Acid Side Chain Status")
2371                      == 0) {
2372             if (StringCmp(ufp->data.ptrvalue, "On") == 0)
2373                 pars->NTResiduesOn = TRUE;
2374             else
2375                 pars->NTResiduesOn = FALSE;
2376         } else if (StringCmp(oip->str, "Nucleic Side Chain Render") == 0) {
2377             if (StringCmp(ufp->data.ptrvalue, "Wire Frame") == 0)
2378                 pars->NTResRender = R_WIRE;
2379             else if (StringCmp(ufp->data.ptrvalue, "Tubes") == 0)
2380                 pars->NTResRender = R_STICK;
2381             else if (StringCmp(ufp->data.ptrvalue, "Ball & Stick") == 0)
2382                 pars->NTResRender = R_BALLNSTICK;
2383             else if (StringCmp(ufp->data.ptrvalue, "Fat Tubes") == 0)
2384                 pars->NTResRender = R_THICKWIRE;
2385             else if (StringCmp(ufp->data.ptrvalue, "Space Fill") == 0)
2386                 pars->NTResRender = R_SPACE;
2387         }
2388             else if (StringCmp(oip->str, "Nucleic Acid Side Chain Color")
2389                      == 0) {
2390             sscanf(ufp->data.ptrvalue, "%hd %hd %hd", &rgb_short[0],
2391                    &rgb_short[1], &rgb_short[2]);
2392             pars->NTResColRGB[0] = (Uint1) rgb_short[0];
2393             pars->NTResColRGB[1] = (Uint1) rgb_short[1];
2394             pars->NTResColRGB[2] = (Uint1) rgb_short[2];
2395             pars->NTResColor = C_BYCHOICE;
2396         } else if (StringCmp(oip->str, "Nucleic Acid Label Status") == 0) {
2397             sscanf(ufp->data.ptrvalue, "%hd", &num);
2398             pars->NTBBLabelInterval = (Uint1) num;
2399         } else if (StringCmp(oip->str, "Nucleic Acid Label Just") == 0) {
2400             sscanf(ufp->data.ptrvalue, "%hd", &num);
2401             pars->NTBBLabelJust = (Uint1) num;
2402         } else if (StringCmp(oip->str, "Nucleic Acid Label Scale") == 0) {
2403             sscanf(ufp->data.ptrvalue, "%hd", &num);
2404             pars->NTBBLabelScale = (Uint1) num;
2405         } else if (StringCmp(oip->str, "Nucleic Acid Label Style") == 0) {
2406             sscanf(ufp->data.ptrvalue, "%hd", &num);
2407             pars->NTBBLabelStyle = (Uint1) num;
2408         }
2409 
2410         ufp = ufp->next;
2411     }
2412 
2413     return pars;
2414 }
2415 
2416 /*-------------------------------------*/
2417 void Cn3DRemoveUserDefinedFeatureFromBiostruc(PDNMS pdnmsThis)
2418 {
2419     BiostrucPtr bsp;
2420     BiostrucFeatureSetPtr bsfsp, bsfsp_prev = NULL, bsfsp_curr = NULL;
2421     ValNodePtr descr = NULL;
2422 
2423     if (!pdnmsThis || !pdnmsThis->data.ptrvalue ||
2424         !(bsp = ((PMSD) pdnmsThis->data.ptrvalue)->pbsBS))
2425         return;
2426 
2427     /* assuming these feature data always occur at the tail end of the feature list,
2428        unhook them from the biostruc and free them */
2429     bsfsp = bsp->features;
2430     while (bsfsp) {
2431         if(bsfsp->descr != NULL) {
2432             descr = bsfsp->descr;
2433             if (descr->choice == 1) {
2434                 if (StringCmp(descr->data.ptrvalue, "User Defined Features") == 0) {
2435                     if (bsfsp_prev)
2436                         bsfsp_prev->next = NULL;
2437                     bsfsp_curr = bsfsp;
2438                     break;
2439                 }
2440             }
2441         }
2442         bsfsp_prev = bsfsp;
2443         bsfsp = bsfsp->next;
2444     }
2445     BiostrucFeatureSetFree(bsfsp_curr);
2446 }
2447 
2448 /*-------------------------------------*/
2449 static void Cn3DIndexUserDefinedFeatureForMSD(PDNMS pdnmsThis)
2450 {
2451     PMSD pmsdThis = NULL;
2452     BiostrucPtr bsp = NULL;
2453     BiostrucFeatureSetPtr bsfsp = NULL;
2454     ValNodePtr descr = NULL;
2455     SpecialFeaturePtr sfpThis = NULL;
2456     SpecialFeatureInfoPtr sfipThis = NULL;
2457     UserObjectPtr ubp = NULL;
2458     ValNodePtr llp = NULL, ppp = NULL;
2459     Boolean UserDefinedFeatureFound = FALSE;
2460     Boolean NewUserDefinedFeature = FALSE;
2461 
2462     if (pdnmsThis == NULL)
2463         return;
2464 
2465     pmsdThis = pdnmsThis->data.ptrvalue;
2466     bsp = pmsdThis->pbsBS;
2467     bsfsp = bsp->features;
2468     while (bsfsp) {
2469         descr = bsfsp->descr;
2470         UserDefinedFeatureFound = FALSE;
2471         NewUserDefinedFeature = FALSE;
2472 
2473         while (descr) {
2474             if (descr->choice == BiostrucFeatureSetDescr_name) {
2475                 if (StringCmp(descr->data.ptrvalue, "User Defined Features") == 0) {
2476                     UserDefinedFeatureFound = TRUE;
2477                     sfipThis = GetUserDefinedFeature(bsfsp->id);
2478                     if (sfipThis == NULL) {
2479                         sfipThis = SpecialFeatureInfoNew();
2480                         sfipThis->isOn = FALSE;
2481                         NewUserDefinedFeature = TRUE;
2482                     }
2483                 }
2484             } else if (descr->choice == BiostrucFeatureSetDescr_other_comment) {
2485                 if (NewUserDefinedFeature) {
2486                     if (StringCmp(descr->data.ptrvalue, "On") == 0) {
2487                         sfipThis->isOn = TRUE;
2488                     } else if (descr->data.ptrvalue != NULL) {
2489                         sfipThis->description =
2490                             StringSave(descr->data.ptrvalue);
2491                     }
2492                 }
2493             }
2494             descr = descr->next;
2495         }
2496 
2497         if (UserDefinedFeatureFound) {
2498             BiostrucFeaturePtr bsfp = bsfsp->features;
2499 
2500             if (NewUserDefinedFeature) {
2501                 sfipThis->name = StringSave(bsfp->name);
2502                 ppp = bsfp->Property_property;
2503                 ubp = ppp->data.ptrvalue;
2504                 sfipThis->parsSpecial =
2505                     GetSpecialParsForUserDefinedFeature(ubp);
2506 
2507                 iNumFeatures++;
2508                 sfpThis = ValNodeNew(NULL);
2509                 if (sfpThis) {
2510                     ValNodePtr sfpBefore = NULL, sfpAfter = sfpThis_head;
2511 
2512                     sfpThis->choice = bsfsp->id;
2513                     sfpThis->data.ptrvalue = sfipThis;
2514 
2515                     /* add to list in order of id (choice) */
2516                     while (sfpAfter && sfpAfter->choice < sfpThis->choice) {
2517                         sfpBefore = sfpAfter;
2518                         sfpAfter = sfpAfter->next;
2519                     }
2520                     sfpThis->next = sfpAfter;
2521                     if (!sfpAfter) sfpThis_tail = sfpThis;
2522                     if (sfpBefore)
2523                         sfpBefore->next = sfpThis;
2524                     else
2525                         sfpThis_head = sfpThis;
2526                 }
2527             }
2528 
2529             llp = CopyLocation(bsfp->Location_location);
2530             ValNodeAddPointer(&(sfipThis->pvnLocations), 0, (VoidPtr) llp); /* store location for each model */
2531             ValNodeAddPointer(&(sfipThis->pvnModels), 0, (VoidPtr) pmsdThis);
2532 
2533             Cn3DApplyUserDefinedFeatureToMGD(pmsdThis, llp, bsfsp->id, sfipThis);
2534         }
2535 
2536         bsfsp = bsfsp->next;
2537     }
2538 
2539     /* remove features so they can be edited; will be re-added upon save */
2540     Cn3DRemoveUserDefinedFeatureFromBiostruc(pdnmsThis);
2541 }
2542 
2543 /*-------------------------------------*/
2544 void Cn3DIndexUserDefinedFeature(void)
2545 {
2546     PDNMS pdnmsThis = NULL, pdnmsThisSlave = NULL;
2547     PMSD pmsdThis = NULL;
2548     PDNMM pdnmmHead = NULL;
2549     PMMD pmmdThis = NULL;
2550 
2551     SpecialFeaturePtr sfpThis = NULL;
2552 
2553     pdnmsThis = GetSelectedModelstruc();
2554     if (!pdnmsThis)
2555         return;
2556 
2557     iNumFeatures = 0;
2558 
2559     Cn3DIndexUserDefinedFeatureForMSD(pdnmsThis);
2560     pdnmsThisSlave = ((PMSD) (pdnmsThis->data.ptrvalue))->pdnmsSlaves;
2561     while (pdnmsThisSlave) {
2562         Cn3DIndexUserDefinedFeatureForMSD(pdnmsThisSlave);
2563         pdnmsThisSlave = pdnmsThisSlave->next;
2564     }
2565 
2566     sfpGlobal = sfpThis_head;
2567     sfpThis = sfpGlobal;
2568 
2569     Cn3D_SyncMenuHighlightWithOnOff();
2570     UpdateEditFeatureList();
2571 }
2572 
2573 /*-------------------------------------------*/
2574 static void ClearSpecialFeature(void)
2575 {
2576     SpecialFeaturePtr sfpThis = NULL, next = NULL;
2577 
2578     sfpThis = sfpGlobal;
2579     while (sfpThis) {
2580         next = sfpThis->next;
2581         sfpThis->next = NULL;
2582         sfpThis = SpecialFeatureFree(sfpThis);
2583         sfpThis = next;
2584     }
2585 
2586     sfpGlobal = NULL;
2587     sfpThis_head = NULL;
2588     sfpThis_tail = NULL;
2589     parsSpecial = NULL;
2590     iNumFeatures = 0;
2591     iEditedFeature = 0;
2592 }
2593 
2594 
2595 /*-------------------------------------------*/
2596 extern void ClearDomainData(void); /* in cn3dmodl.c */
2597 
2598 void ClearRest(void)
2599 {
2600     if (sfpGlobal != NULL)
2601         ClearSpecialFeature();
2602 
2603     ClearDomainData();
2604 }
2605 
2606 

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

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