// TSPrimaryItem.h: interface for the PrimaryItem class.
//
/////////////////////////////////////////////////////////////////////////

#ifndef TSPRIMARYITEM_H_
#define TSPRIMARYITEM_H_

#pragma warning( push, 1 )
#include "DisableSTLWarnings.h"
#include <list>
#pragma warning( pop )
#include "DisableSTLUsageWarnings.h"

#include "TSApi.h"
#include "TSItem.h"
#include "TSProject.h"
#include "TSString.h"
#include "TSTransition.h"

// This class defines a primary item.

class TS_API TSPrimaryItem : public TSItem
{
  friend class TSServer;
  public:
    // Constructors/destructors/operator =
    TSPrimaryItem( TSServer& server, int nTableId = 0, int nItemId = 0 );
    TSPrimaryItem( TSServer& server, const TSProject& project, int nItemNumber = 0 );
    TSPrimaryItem( const TSPrimaryItem& that );
    virtual ~TSPrimaryItem();
    TSPrimaryItem& operator = ( const TSPrimaryItem& that );

    // Accessor methods:
    int             GetItemNumber() const { return m_nItemNumber; }
    const TSString& GetItemType() const   { return m_sItemType; }
    int             GetProjectId() const  { return m_nProjectId; }
    int             GetStateId() const    { return m_nStateId; }
    // These Set accessors allow modification when m_nMode is not == to TS_TRANSITION_STARTED.
    virtual int     SetItemId( int nNewItemId );
    int             SetItemNumber( int nNewItemNumber );
    int             SetProjectId( int nNewProjectId );
    virtual int     SetTableId( int nNewTableId );

    // The CancelTransition method clears the lock on this record. It is
    //  for use after a call to StartTransition, but when FinishTransition
    //  will not be called.
    // This requires a roundtrip to the server.
    virtual int CancelTransition();

    // This FinishSubmit method has the same functionality as TSItem's
    //  FinishSubmit. However, m_nItemNumber gets populated.
    // This requires a roundtrip to the server.
    virtual int FinishSubmit();

    // The FinishTransition method is used to transition the item in the
    //  database after field values in the field list (obtained from
    //  StartTransition) have been set. This method will only send fields
    //  that have been modified back to the server. After a successful
    //  database update, the lock (if it exists) will be removed. This
    //  method can return TS_LOCK_UNAVAILABLE if the lock has expired
    //  and another user has taken the lock.
    // This requires a roundtrip to the server.
    virtual int FinishTransition();

    // The GetTransitionList method returns a list of TSTransition records
    //  in the results list that indicate which transitions are valid for
    //  this item. Either the table id and item id, or the project id and
    //  item number must be preset.
    // This requires a roundtrip to the server.
    virtual int GetTransitionList( TSTransitionList& results );

    // This Read method works like the TSItem's Read, but also populates
    //  the m_nProjectId, m_nItemNumber, m_nStateId, and m_sItemType members.
    //  This Read method will either read by table id and item id, or if
    //  either are 0 and the project id and item number are set, it will
    //  read by project id and item number.
    // This requires a roundtrip to the server.
    virtual int Read();

    // This ReadByNumber method populates the project id and item number
    //  members and clears item id before calling Read.
    int ReadByNumber( int nProjectId, int nItemNumber );

    // This StartSubmit method has the same functionality as TSItem's
    //  StartSubmit. However, a project id must be specified for a submit
    //  of a primary item.
    // This requires a roundtrip to the server.
    virtual int StartSubmit();

    // The StartSubmitIntoProject method sets the project id member
    //  before calling StartSubmit.
    int StartSubmitIntoProject( int nProjectId );
    int StartSubmitIntoProject( TSProject& project );

    // The StartTransition method should be used to fill in this item as
    //  appropriate for a transition. StartTransition populates the item
    //  and orders fields as they would be for the transition, including
    //  filling out field selection lists. The three other member lists of
    //  a TSItem: changeList, attachmentList and linkList, will not be
    //  updated. The transition id, name, or item is used to indicate which
    //  transition to use. Either the table id and item id or the project
    //  id and item number must be preset.
    // This method locks this record. Note that while the record is locked,
    //  any other user (via API or browser interface) will receive an error
    //  (TS_LOCK_UNAVAILABLE for API) if they attempt to transition the same
    //  record. The time a lock is held is set by the TeamTrack administrator.
    // Note: TeamShare will ensure transition names from the same state are
    //  unique in 5.0.
    // This requires a roundtrip to the server.
    virtual int StartTransition( int nTransitionId );
    virtual int StartTransition( TSString sTransitionName );
    virtual int StartTransition( const TSTransition& transitionItem );

    // For debugging
    TSString StringDump( TSString sIndentation );

  protected:
    // Only intended to be called by member methods of TSServer.
    int Receive( TSSocket* socket );

    // The IsValid method is called from the server and in Read to make
    //  sure that (table id and item id) or (project id and item number)
    //  have been set.
    virtual bool IsValid() const;

    int      m_nItemNumber;   // Int version of item number
    int      m_nProjectId;    // Project id the item is within
    int      m_nStateId;      // Current state id of item
    TSString m_sItemType;     // Contains prefix of the item, e.g. incident type

};

typedef std::list< TSPrimaryItem* > TSPrimaryItemList;

#endif

