
#include "linkofgod.h"
//------------------------------------------------------------------------------

ostream& operator<<(ostream& os, const God& g)
{
    os << g.name << ": " << g.mythology << ", "
        << g.vehicle << ", " << g.weapon;
    return os;
}
//------------------------------------------------------------------------------

/**template<class T>
struct Link {
    T value;
    Link* prev;
    Link* succ;
    Link(const T& v, Link* p = 0, Link* s = 0)
        : value(v), prev(p), succ(s) { }
};*/

/// insert n before p; return n
template<class T>
Link<T>* insert(Link<T>* p, Link<T>* n)
{
    if (n==nullptr) return p;
    if (p==nullptr) return n;
    n->succ = p;
    if (p->prev) p->prev->succ = n;
    n->prev = p->prev;
    p->prev = n;
    return n;
}

//------------------------------------------------------------------------------

template<typename T>
Link<T>* Link<T>::erase()          // remove this object from the list; return this's successor
{
    if (this==0) return 0;
    if (succ) succ->prev = prev;
    if (prev) prev->succ = succ;
    return succ;
}

//------------------------------------------------------------------------------
template<typename T>
Link<T>* Link<T>::find(const T& s) // find s in list;
/// return 0 for "not found"
{
    Link<T>* p = this;
    while(p) {
        if (p->value == s) return p;
        p = p->succ;
    }
    return 0;
}

template<typename T>
Link<T>* Link<T>::add(Link<T>* p, Link<T>* n) {
    if (n==0) return this;
    if (this==0) return n;
    n->prev = this;
    if (succ) succ->prev = n;
    n->succ = succ;
    succ = n;
    return n;
}

template<typename T>
Link<T>* Link<T>::add_ordered(Link<T>* p, Link<T>* n)
{
    if (n==0) return p;
    if (p==0) return n;
    while (n->value > p->value && p->succ) {
        p = p->succ;
    }
    /// p points now to first element with value bigger than value of n or the
    /// last element of the list
    if (n->value > p->value) p = add(p,n);
    else p = insert(p,n);

    // traverse list to return first element
    while (p->prev) p = p->prev;
    return p;
}
//// insert n after this object
//Link* Link::add(Link* n) {
//    if (n==0) return this;
//    if (this==0) return n;
//    n->prev = this;
//    if (succ) succ->prev = n;
//    n->succ = succ;
//    succ = n;
//    return n;
//}//------------------------------------------------------------------------------

template<typename T>
void print_all(Link<T>* p)
{
    cout << "{ ";
    while (p) {
        cout << p->value;
        if (p=(p->next()))
            cout <<  ", ";
    }
    cout << " }";
}
