/* $Id: Entrezgene.cpp 694727 2025-03-10 12:37:42Z ivanov $
 * ===========================================================================
 *
 *                            PUBLIC DOMAIN NOTICE
 *               National Center for Biotechnology Information
 *
 *  This software/database is a "United States Government Work" under the
 *  terms of the United States Copyright Act.  It was written as part of
 *  the author's official duties as a United States Government employee and
 *  thus cannot be copyrighted.  This software/database is freely available
 *  to the public for use. The National Library of Medicine and the U.S.
 *  Government have not placed any restriction on its use or reproduction.
 *
 *  Although all reasonable efforts have been taken to ensure the accuracy
 *  and reliability of the software and data, the NLM and the U.S.
 *  Government do not and cannot warrant the performance or results that
 *  may be obtained by using this software or data. The NLM and the U.S.
 *  Government disclaim all warranties, express or implied, including
 *  warranties of performance, merchantability or fitness for any particular
 *  purpose.
 *
 *  Please cite the author in any work or product based on this material.
 *
 * ===========================================================================
 *
 * Author:  .......
 *
 * File Description:
 *   .......
 *
 * Remark:
 *   This code was originally generated by application DATATOOL
 *   using the following specifications:
 *   'entrezgene.asn'.
 */

// standard includes
#include <ncbi_pch.hpp>

// generated includes
#include <objects/entrezgene/Entrezgene.hpp>

#include <objects/entrezgene/Gene_track.hpp>
#include <objects/entrezgene/Gene_commentary.hpp>
#include <objects/seqfeat/Gene_ref.hpp>
#include <objects/seqfeat/Prot_ref.hpp>
#include <objects/seqfeat/RNA_ref.hpp>
#include <objects/pub/Pub.hpp>
#include <serial/enumvalues.hpp>
#include <serial/iterator.hpp>


// generated classes

BEGIN_NCBI_SCOPE

BEGIN_objects_SCOPE // namespace ncbi::objects::

// destructor
CEntrezgene::~CEntrezgene(void)
{
}

// Locate or create the nomenclature element.  Ensure that the gene symbol is
// always filled in, even if it is not present in the structured elements and
// has to be derived.

CRef<CGene_nomenclature> CEntrezgene::GetNomenclature() const
{
    CRef<CGene_nomenclature> nomen(new CGene_nomenclature);
    nomen->SetStatus(CGene_nomenclature::eStatus_unknown);

    const CGene_ref& gene_ref = GetGene();

    // First choice: the formal-name element.

    if (gene_ref.IsSetFormal_name()) {
        nomen->Assign(gene_ref.GetFormal_name());
    }

    // Second choice: look in the properties
    // Note that this structure is deprecated.

    if ( ! nomen->IsSetSymbol() ) {

        for ( const auto& root_properties : GetProperties() ) {

            if ((root_properties->GetType() == CGene_commentary::eType_comment) &&
                 root_properties->IsSetLabel() && (root_properties->GetLabel() == "Nomenclature" )) {

                // found it!

                if (root_properties->IsSetProperties()) {

                    // Look for the symbol and full name.

                    for ( const auto& nomen_properties : root_properties->GetProperties() ) {

                        if ((nomen_properties->GetType() == CGene_commentary::eType_property) &&
                             nomen_properties->IsSetLabel() && nomen_properties->IsSetText()) {

                            const string& label(nomen_properties->GetLabel());
                            const string& text(nomen_properties->GetText());

                            if (text.empty()) {
                                continue;
                            }

                            if (label == "Official Symbol") {

                                nomen->SetSymbol(text);
                                nomen->SetStatus(CGene_nomenclature::eStatus_official);

                            } else if (label == "Official Full Name") {

                                nomen->SetName(text);
                                nomen->SetStatus(CGene_nomenclature::eStatus_official);

                            } else if (label == "Interim Symbol") {

                                nomen->SetSymbol(text);
                                nomen->SetStatus(CGene_nomenclature::eStatus_interim);

                            } else if (label == "Interim Full Name") {

                                nomen->SetName(text);
                                nomen->SetStatus(CGene_nomenclature::eStatus_interim);
                            }
                        }

                    } // for each nomenclature property element
                }

                break; // we found it
            }

        } // for each property element
    }

    // Ensure that the symbol is filled in.

    if ( ! nomen->IsSetSymbol() ) {

        nomen->SetSymbol(GetSymbol());
    }

    return nomen;
}

// Produce a standard description of the gene.

string CEntrezgene::GetDescription() const 
{
    string desc;

    // Description:
    //
    //     first of:
    //         Eg.gene.desc or
    //         Eg.prot.desc or
    //         first Eg.prot.name or
    //         Eg.rna.ext.name or
    //         Eg.type

    if (GetGene().IsSetDesc()) {
        desc = GetGene().GetDesc();
    }
    else if (IsSetProt() && GetProt().IsSetDesc()) {
        desc = GetProt().GetDesc();
    }
    else if (IsSetProt() && GetProt().IsSetName() && ( ! GetProt().GetName().empty() ) ) {
        desc = *(GetProt().GetName().begin());
    }
    else if (IsSetRna() && GetRna().IsSetExt() && GetRna().GetExt().IsName()) {
        desc = GetRna().GetExt().GetName();
    }
    else {
        const bool allowBadValue = true;
        desc = GetTypeInfo_enum_EType()->FindName(GetType(), allowBadValue);
    }

    if (desc == "other") {
        desc.clear();
    }

    return desc;
}

// Produce the gene symbol.
string CEntrezgene::GetSymbol() const
{
    // First choice: get from EG.locus

    if (GetGene().IsSetLocus()) {
        return GetGene().GetLocus();
    }

    // Second choice: get from EG.locus_tag

    if (GetGene().IsSetLocus_tag()) {
        return GetGene().GetLocus_tag();
    }

    // Third choice: get from EG.gene.syn[0]

    if (GetGene().IsSetSyn() && ( ! GetGene().GetSyn().empty() )) {
        return (*(GetGene().GetSyn().begin()));
    }

    // Last choice: construct it as "LOC" + geneid

    string loc = "LOC" + to_string(GetTrack_info().GetGeneid());
    return loc;
}

// Try to find a root-level comment with the given heading.

CRef<CGene_commentary> CEntrezgene::FindComment(const string& heading) const
{
    CRef<CGene_commentary> found_comment;

    for ( const auto root_comment : GetComments() ) {
        if (root_comment->IsSetHeading() && (root_comment->GetHeading() == heading)) {
            found_comment = root_comment;
            break;
        }
    }

    return found_comment;
}

// Extract all PMIDs.

void CEntrezgene::GetPubs(set<NCBI_NS_NCBI::TEntrezId>& pubs_out) const
{
    CTypeConstIterator<CPub> iter(*this);
    for (const auto& pub : iter) {
        if (pub.IsPmid()) {
            pubs_out.insert(pub.GetPmid());
        }
    }
}

END_objects_SCOPE // namespace ncbi::objects::

END_NCBI_SCOPE

/* Original file checksum: lines: 140737443291791, chars: 1733, CRC32: c6c80683 */
