// $Id: gc_phase.cpp,v 1.10 2018/01/03 21:32:55 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#include <cassert>

#include "gc_locus.h"
#include "gc_phase.h"
#include "gc_phase_err.h"
#include "wx/log.h"
#include "wx/tokenzr.h"

//------------------------------------------------------------------------------------

gcUnphasedMarkers::gcUnphasedMarkers()
{
}

gcUnphasedMarkers::~gcUnphasedMarkers()
{
}

wxString
gcUnphasedMarkers::AsString() const
// used for DebugDump and for outputting XML file
{
    wxString retVal;
    for(std::set<long>::const_iterator iter = begin(); iter != end(); iter++)
    {
        if(iter != begin()) retVal += " ";
        retVal += wxString::Format("%d",(int)(*iter));
    }
    return retVal;
}

size_t
gcUnphasedMarkers::NumMarkers() const
{
    return std::set<long>::size();
}

void
gcUnphasedMarkers::AddMarker(long marker)
{
    insert(marker);
}

void
gcUnphasedMarkers::Merge(const gcUnphasedMarkers & unphased)
{
    for(std::set<long>::const_iterator i = unphased.begin(); i != unphased.end(); i++)
    {
        AddMarker(*i);
    }
}

void
gcUnphasedMarkers::DebugDump(wxString prefix) const
{
    wxLogDebug("%sunphased markers: %s",      // EWDUMPOK
               prefix.c_str(),
               AsString().c_str());
}

void
gcUnphasedMarkers::ReadFromString(wxString line)
{
    wxStringTokenizer tokenizer(line);
    while(tokenizer.HasMoreTokens())
    {
        wxString longToken = tokenizer.GetNextToken();
        long longVal;
        if(! longToken.ToLong(&longVal))
        {
            throw gc_phase_marker_not_legal(longToken);
        }
        AddMarker(longVal);
    }
}

bool
gcUnphasedMarkers::operator!=(const gcUnphasedMarkers& markers) const
{
    return (!( *this == markers) );
}

bool
gcUnphasedMarkers::HasZero() const
{
    if(find(0) != end()) return true;
    return false;
}

long
gcUnphasedMarkers::Smallest() const
{
    assert(!empty());
    return *(begin());
}

long
gcUnphasedMarkers::Largest() const
{
    assert(!empty());
    return *(end());
}

void
gcUnphasedMarkers::ShiftNegsUp()
{
    gcUnphasedMarkers tmpStorage;
    for(iterator i = begin(); i != end(); )
    {
        assert(*i != 0);
        if(*i < 0)
        {
            tmpStorage.insert((*i)+1);
            erase(i++);
        }
        else
        {
            i++;
        }
    }
    for(gcUnphasedMarkers::iterator i=tmpStorage.begin(); i != tmpStorage.end(); i++)
    {
        insert(*i);
    }
}

void
gcUnphasedMarkers::CheckAgainstLocations(const gcLocus& locusRef) const
{
    if(locusRef.HasLocations())
    {
        std::vector<long> locs = locusRef.GetLocations();
        std::set<long> locSet;
        for(size_t i=0; i < locs.size(); i++)
        {
            locSet.insert(locs[i]);
        }
        for(const_iterator iter=begin(); iter != end(); iter++)
        {
            if(locSet.find(*iter) == locSet.end())
            {
                throw gc_phase_not_location(*iter,locusRef.GetName());
            }
        }
    }
}

//____________________________________________________________________________________
