/******************************************** 
copyright 1999 McMillan Enterprises, Inc.
www.mcmillan-inc.com
 *********************************************/
#if !defined(PWOMSEQUENCE_H_INCLUDED_)
#define PWOMSEQUENCE_H_INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "PWOBase.h"
#include "PWOSequence.h"


class PWOList;

class PWOListMmbr: public PWOBase {
    PWOList &_parent;
    int _ndx;
  public:
    PWOListMmbr(PyObject *obj, PWOList &parent, int ndx);
    virtual ~PWOListMmbr(){}
    ;
    PWOListMmbr &operator = (const PWOBase &other);
};

class PWOList: public PWOSequence {
  public:
    PWOList(int size = 0): PWOSequence(PyList_New(size)) {
        LoseRef(_obj);
    }
    PWOList(const PWOList &other): PWOSequence(other){}
    ;
    PWOList(PyObject *obj): PWOSequence(obj) {
        _violentTypeCheck();
    };
    virtual ~PWOList(){}
    ;

    virtual PWOList &operator = (const PWOList &other) {
        GrabRef(other);
        return  *this;
    };
    PWOList &operator = (const PWOBase &other) {
        GrabRef(other);
        _violentTypeCheck();
        return  *this;
    };
    virtual void _violentTypeCheck() {
        if (!PyList_Check(_obj)) {
            //should probably check the sequence methods for non-0 setitem
            GrabRef(0);
            Fail(PyExc_TypeError, "Not a mutable sequence");
        }
    };
    //PySequence_DelItem    ##lists
    bool delItem(int i) {
        int rslt = PySequence_DelItem(_obj, i);
        if (rslt ==  - 1)
          Fail(PyExc_RuntimeError, "cannot delete item");
        return true;
    };
    //PySequence_DelSlice   ##lists
    bool delSlice(int lo, int hi) {
        int rslt = PySequence_DelSlice(_obj, lo, hi);
        if (rslt ==  - 1)
          Fail(PyExc_RuntimeError, "cannot delete slice");
        return true;
    };
    //PySequence_GetItem    ##lists - return PWOListMmbr (mutable) otherwise just a PWOBase
    PWOListMmbr operator[](int i) {
        // can't be virtual
        //PyObject* o = PySequence_GetItem(_obj, i); assumes item is valid
        PyObject *o = PyList_GetItem(_obj, i); // get a "borrowed" refcount
        //Py_XINCREF(o);
        //if (o == 0)
        //      Fail(PyExc_IndexError, "index out of range");
        return PWOListMmbr(o,  *this, i); // this increfs
    };
    //PySequence_SetItem    ##Lists
    void setItem(int ndx, PWOBase &val) {
        //int rslt = PySequence_SetItem(_obj, ndx, val); - assumes old item is valid
        int rslt = PyList_SetItem(_obj, ndx, val);
        val.disOwn(); //when using PyList_SetItem, he steals my reference
        if (rslt ==  - 1)
          Fail(PyExc_IndexError, "Index out of range");
    };
    void setItem(int ndx, PyObject *val) {
        //int rslt = PySequence_SetItem(_obj, ndx, val); - assumes old item is valid
        int rslt = PyList_SetItem(_obj, ndx, val);
        if (rslt ==  - 1)
          Fail(PyExc_IndexError, "Index out of range");
    };
    //PySequence_SetSlice   ##Lists
    void setSlice(int lo, int hi, const PWOSequence &slice) {
        int rslt = PySequence_SetSlice(_obj, lo, hi, slice);
        if (rslt ==  - 1)
          Fail(PyExc_RuntimeError, "Error setting slice");
    };
    //PyList_Append
    PWOList &append(const PWOBase &other) {
        int rslt = PyList_Append(_obj, other);
        if (rslt ==  - 1) {
            PyErr_Clear(); //Python sets one 
            Fail(PyExc_RuntimeError, "Error appending");
        };
        return  *this;
    };
    //PyList_AsTuple
    // problem with this is it's created on the heap
    //virtual PWOTuple& asTuple() const {
    //      PyObject* rslt = PyList_AsTuple(_obj);
    //      PWOTuple rtrn = new PWOTuple(rslt);
    //      Py_XDECREF(rslt);       //AsTuple set refcnt to 1, PWOTuple(rslt) increffed
    //      return *rtrn;
    //};
    //PyList_GetItem - inherited OK
    //PyList_GetSlice - inherited OK
    //PyList_Insert
    PWOList &insert(int ndx, PWOBase &other) {
        int rslt = PyList_Insert(_obj, ndx, other);
        if (rslt ==  - 1) {
            PyErr_Clear(); //Python sets one 
            Fail(PyExc_RuntimeError, "Error inserting");
        };
        return  *this;
    };
    //PyList_New
    //PyList_Reverse
    PWOList &reverse() {
        int rslt = PyList_Reverse(_obj);
        if (rslt ==  - 1) {
            PyErr_Clear(); //Python sets one 
            Fail(PyExc_RuntimeError, "Error reversing");
        };
        return  *this; //HA HA - Guido can't stop me!!!
    };
    //PyList_SetItem - using abstract
    //PyList_SetSlice - using abstract
    //PyList_Size - inherited OK
    //PyList_Sort
    PWOList &sort() {
        int rslt = PyList_Sort(_obj);
        if (rslt ==  - 1) {
            PyErr_Clear(); //Python sets one 
            Fail(PyExc_RuntimeError, "Error sorting");
        };
        return  *this; //HA HA - Guido can't stop me!!!
    };
};

#endif // PWOMSEQUENCE_H_INCLUDED_
