/* $Id: Seq_annot.cpp 649481 2022-05-04 15:46:34Z grichenk $
 * ===========================================================================
 *
 *                            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 specifications from the data definition file
 *   'seq.asn'.
 */

// standard includes

// generated includes
#include <ncbi_pch.hpp>
#include <objects/seq/Seq_annot.hpp>
#include <objects/general/Date.hpp>
#include <objects/seqfeat/Seq_feat.hpp>
#include <objects/misc/error_codes.hpp>


#define NCBI_USE_ERRCODE_X   Objects_SeqAnnot

// generated classes

BEGIN_NCBI_SCOPE

BEGIN_objects_SCOPE // namespace ncbi::objects::

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


void CSeq_annot::AddName(const string &name)
{
    SetNameDesc(name);
}

void CSeq_annot::SetNameDesc(const string &name)
{
    //NB: this used list::remove_if(), which is not portable to Windows
    TDesc::Tdata::iterator iter = SetDesc().Set().begin();
    for ( ;  iter != SetDesc().Set().end();  ) {
        if ((*iter)->IsName() ) {
            iter = SetDesc().Set().erase(iter);
        } else {
            ++iter;
        }
    }

    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetName(name);
    SetDesc().Set().push_back(desc);
}


void CSeq_annot::SetTitle(const string& title)
{
    SetTitleDesc(title);
}


void CSeq_annot::AddTitle(const string& title)
{
    SetTitleDesc(title);
}


void CSeq_annot::SetTitleDesc(const string &title)
{
    TDesc::Tdata::iterator iter = SetDesc().Set().begin();
    for ( ;  iter != SetDesc().Set().end();  ) {
        if ((*iter)->IsTitle() ) {
            iter = SetDesc().Set().erase(iter);
        } else {
            ++iter;
        }
    }

    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetTitle(title);
    SetDesc().Set().push_back(desc);
}


void CSeq_annot::AddComment(const string &comment)
{
    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetComment(comment);
    SetDesc().Set().push_back(desc);
}


void CSeq_annot::SetCreateDate(const CTime& dt)
{
    CRef<CDate> date(new CDate(dt));
    SetCreateDate(*date);
}


void CSeq_annot::SetCreateDate(CDate& date)
{
    TDesc::Tdata::iterator iter = SetDesc().Set().begin();
    for ( ;  iter != SetDesc().Set().end();  ) {
        if ((*iter)->IsCreate_date() ) {
            iter = SetDesc().Set().erase(iter);
        } else {
            ++iter;
        }
    }

    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetCreate_date(date);
    SetDesc().Set().push_back(desc);
}


void CSeq_annot::SetUpdateDate(const CTime& dt)
{
    CRef<CDate> date(new CDate(dt));
    SetUpdateDate(*date);
}


void CSeq_annot::SetUpdateDate(CDate& date)
{
    TDesc::Tdata::iterator iter = SetDesc().Set().begin();
    for ( ;  iter != SetDesc().Set().end();  ) {
        if ((*iter)->IsUpdate_date() ) {
            iter = SetDesc().Set().erase(iter);
        } else {
            ++iter;
        }
    }

    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetUpdate_date(date);
    SetDesc().Set().push_back(desc);
}


void CSeq_annot::AddUserObject(CUser_object& obj)
{
    CRef<CAnnotdesc> desc(new CAnnotdesc());
    desc->SetUser(obj);
    SetDesc().Set().push_back(desc);
}


bool CSeq_annot::IsFtable(void) const
{
    return IsSetData () && GetData ().IsFtable ();
}

bool CSeq_annot::IsAlign(void) const
{
    return IsSetData () && GetData ().IsAlign ();
}

bool CSeq_annot::IsGraph(void) const
{
    return IsSetData () && GetData ().IsGraph ();
}

bool CSeq_annot::IsIds(void) const
{
    return IsSetData () && GetData ().IsIds ();
}

bool CSeq_annot::IsLocs(void) const
{
    return IsSetData () && GetData ().IsLocs ();
}

bool CSeq_annot::IsSeq_table(void) const
{
    return IsSetData () && GetData ().IsSeq_table ();
}


/////////////////////////////////////////////////////////////////////////////
// Zoom level manipulation functions
/////////////////////////////////////////////////////////////////////////////

static const size_t NCBI_ANNOT_TRACK_ZOOM_LEVEL_SUFFIX_LEN = 2;


bool CSeq_annot::ExtractZoomLevel(const string& full_name, string* acc_ptr, int* zoom_level_ptr)
{
    SIZE_TYPE pos = full_name.find(NCBI_ANNOT_TRACK_ZOOM_LEVEL_SUFFIX);
    if ( pos != NPOS ) {
        if ( acc_ptr ) {
            *acc_ptr = full_name.substr(0, pos);
        }
        SIZE_TYPE num_pos = pos + NCBI_ANNOT_TRACK_ZOOM_LEVEL_SUFFIX_LEN;
        // assuming single asterisk "*" as wildcard for all zoom levels
        if ( num_pos+1 == full_name.size() && full_name[num_pos] == '*' ) {
            if ( zoom_level_ptr ) {
                *zoom_level_ptr = -1;
            }
            return true;
        }
        else {
            try {
                int zoom_level = NStr::StringToInt(full_name.substr(num_pos));
                if ( zoom_level_ptr ) {
                    *zoom_level_ptr = zoom_level;
                }
                return true;
            }
            catch ( CException& ) {
                // invalid zoom level suffix, assume no zoom level
            }
        }
    }
    // no explicit zoom level
    if ( acc_ptr ) {
        *acc_ptr = full_name;
    }
    if ( zoom_level_ptr ) {
        *zoom_level_ptr = 0;
    }
    return false;
}


string CSeq_annot::CombineWithZoomLevel(const string& acc, int zoom_level)
{
    string ret = acc;
    AddZoomLevel(ret, zoom_level);
    return ret;
}


void CSeq_annot::AddZoomLevel(string& acc, int zoom_level)
{
    int incl_level;
    if ( !ExtractZoomLevel(acc, 0, &incl_level) ) {
        if ( zoom_level == -1 ) {
            // wildcard
            acc += NCBI_ANNOT_TRACK_ZOOM_LEVEL_SUFFIX "*";
        }
        else {
            acc += NCBI_ANNOT_TRACK_ZOOM_LEVEL_SUFFIX;
            acc += NStr::IntToString(zoom_level);
        }
    }
    else if ( incl_level != zoom_level ) {
        // different zoom level
        NCBI_THROW_FMT(CSeqAnnotException, eZoom,
                       "AddZoomLevel: Incompatible zoom levels: "
                       <<acc<<" vs "<<zoom_level);
    }
}


const char* CSeqAnnotException::GetErrCodeString(void) const
{
    switch (GetErrCode()) {
    case eZoom: return "Bad zoom level";
    default:    return CException::GetErrCodeString();
    }
}


END_objects_SCOPE // namespace ncbi::objects::

END_NCBI_SCOPE

#undef NCBI_USE_ERRCODE_X

/* Original file checksum: lines: 64, chars: 1875, CRC32: 377b3912 */
