/************************/
/* file class_equipot.h */
/************************/

/*
 *  Classes to handle info on nets
 */

#ifndef __CLASSES_NETINFO__
#define __CLASSES_NETINFO__

#include "class_netclass.h"

// Forward declaration:
class NETINFO_ITEM;


/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */
/*****************************/
/* flags for a RATSNEST_ITEM */
/*****************************/
#define CH_VISIBLE          1   /* affichage permanent demande */
#define CH_UNROUTABLE       2   /* non route par l'autorouteur */
#define CH_ROUTE_REQ        4   /* doit etre route par l'autorouteur */
#define CH_ACTIF            8   /* chevelu non encore routé */
#define LOCAL_RATSNEST_ITEM 0x8000    /* indique un chevelu reliant 2 pins d'un meme
                                       *  module pour le calcul des chevelus relatifs a 1 seul module */

class RATSNEST_ITEM
{
private:
    int    m_NetCode;   // netcode ( = 1.. n ,  0 is the value used for not connected items)

public:
    int    m_Status;        // State: see previous defines (CH_ ...)
    D_PAD* m_PadStart;      // pointer to the starting pad
    D_PAD* m_PadEnd;        // pointer to ending pad
    int    m_Lenght;        // lenght of the line (temporary used in some calculations)

    /* constructor */
    RATSNEST_ITEM();

    /**
     * Function GetNet
     * @return int - the net code.
     */
    int GetNet() const
    {
        return m_NetCode;
    }


    void SetNet( int aNetCode )
    {
        m_NetCode = aNetCode;
    }


    /** function Draw
     */
    void Draw( WinEDA_DrawPanel* panel, wxDC* DC, int aDrawMode, const wxPoint& offset );
};

/***************************************************************/
/******************* class NETINFO *****************************/
/***************************************************************/


class NETINFO_LIST
{
private:
    BOARD* m_Parent;
    std::vector<NETINFO_ITEM*> m_NetBuffer;                     // nets buffer list (name, design constraints ..

public:
    std::vector<D_PAD*>        m_PadsFullList;                  // Entry for a sorted pad list (used in ratsnest calculations)

public:
    NETINFO_LIST( BOARD* aParent );
    ~NETINFO_LIST();

    /** Function GetItem
     * @param aNetcode = netcode to identify a given NETINFO_ITEM
     * @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its netcode, or NULL if not found
     */
    NETINFO_ITEM* GetNetItem( int aNetcode );

    /**
     * Function GetCount
     * @return the number of nets ( always >= 1 )
     * becuse the first net is the "not connected" net and always exists
     */
    unsigned GetCount() { return m_NetBuffer.size(); }

    /**
     * Function Append
     * adds \a aNewElement to the end of the list.
     */
    void AppendNet( NETINFO_ITEM* aNewElement );

    /** Function DeleteData
     * delete the list of nets (and free memory)
     */
    void DeleteData();

    /** Function BuildListOfNets
     * Build or rebuild the list of NETINFO_ITEM m_NetBuffer
     * The list is sorted by names.
     */
    void BuildListOfNets();

    /** Function GetPadsCount
     * @return the number of pads in board
     */
    unsigned     GetPadsCount()
    {
        return m_PadsFullList.size();
    }


    /** Function GetPad
     * @return the pad idx from m_PadsFullList
     */
    D_PAD* GetPad( unsigned aIdx )
    {
        if( aIdx < m_PadsFullList.size() )
            return m_PadsFullList[aIdx];
        else
            return NULL;
    }


private:

    /** Function Build_Pads_Full_List
     *  Create the pad list
     * initialise:
     *   m_Pads (list of pads)
     * set m_Status_Pcb = LISTE_PAD_OK;
     * and clear for all pads in list the m_SubRatsnest member;
     * clear m_Pcb->m_FullRatsnest
     */
    void Build_Pads_Full_List();
};


/**
 * Class NETINFO_ITEM
 * handles the data for a net
 */
class NETINFO_ITEM
{
private:
    int               m_NetCode;        // this is a number equivalent to the net name
                                        // Used for fast comparisons in rastnest and DRC computations.

    wxString          m_Netname;        // Full net name like /mysheet/mysubsheet/vout used by eeschema

    wxString          m_ShortNetname;   // short net name, like vout from /mysheet/mysubsheet/vout

    wxString          m_NetClassName;   // Net Class name. if void this is equivalent to "default" (the first
                                        // item of the net classes list

    NETCLASS*         m_NetClass;


public:
    int     m_NbNodes;                              // Pads count for this net
    int     m_NbLink;                               // Ratsnets count for this net
    int     m_NbNoconn;                             // Ratsnets remaining to route count
    int     m_Flag;                                 // used in some calculations. Had no special meaning

    std::vector <D_PAD*>         m_ListPad;         // List of pads connected to this net

    unsigned m_RatsnestStartIdx;                    /* Starting point of ratsnests of this net (included)
                                                     * in a general buffer of ratsnest (a vector<RATSNEST_ITEM*> buffer)
                                                     */

    unsigned m_RatsnestEndIdx;                      // Ending point of ratsnests of this net (excluded) in this buffer

    NETINFO_ITEM( BOARD_ITEM* aParent );
    ~NETINFO_ITEM();

    /**
     * Function SetClass
     * sets \a aNetclass into this NET
     */
    void SetClass( const NETCLASS* aNetClass )
    {
        m_NetClass     = (NETCLASS*) aNetClass;
        if( aNetClass )
            m_NetClassName = aNetClass->GetName();
        else
            m_NetClassName = NETCLASS::Default;
    }

    NETCLASS* GetNetClass()
    {
        return m_NetClass;
    }

    /**
     * Function GetClassName
     * returns the class name
     */
    const wxString& GetClassName( ) const
    {
        return m_NetClassName;
    }


    /**
     * Function GetTrackWidth
     * returns the width of tracks used to route this net.
     */
    int GetTrackWidth()
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetTrackWidth();
    }


    /**
     * Function GetTrackMinWidth
     * returns the Minimum value for tracks thickness (used in DRC)
     */
    int GetTrackMinWidth()
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetTrackMinWidth();
    }


    /**
     * Function GetViaSize
     * returns the size of vias used to route this net
     */
    int GetViaSize()
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetViaSize();
    }


    /**
     * Function GetViaDrillSize
     * returns the size of via drills used to route this net
     */
    int GetViaDrillSize()
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetViaDrillSize();
    }


    /**
     * Function GetViaMinSize
     * returns the Minimum value for via sizes (used in DRC)
     */
    int GetViaMinSize()
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetViaMinSize();
    }


    /**
     * Function GetClearance
     * returns the clearance when routing near aBoardItem
     */
    int GetClearance( BOARD_ITEM* aBoardItem )
    {
        wxASSERT( m_NetClass );
        return m_NetClass->GetClearance();
    }


    /* Reading and writing data on files */
    int  ReadDescr( FILE* File, int* LineNum );

    /**
     * Function Save
     * writes the data structures for this object out to a FILE in "*.brd" format.
     * @param aFile The FILE to write to.
     * @return bool - true if success writing else false.
     */
    bool Save( FILE* aFile ) const;


    /** function Draw
     * @todo we actually could show a NET, simply show all the tracks and pads or net name on pad and vias
     */
    void Draw( WinEDA_DrawPanel* panel, wxDC* DC, int aDrawMode, const wxPoint& offset );


    /**
     * Function GetNet
     * @return int - the netcode
     */
    int GetNet() const { return m_NetCode; }
    void SetNet( int aNetCode ) { m_NetCode = aNetCode; }

    int GetNodesCount() const { return m_ListPad.size(); }

    /**
     * Function GetNetname
     * @return const wxString * , a pointer to the full netname
     */
    wxString GetNetname() const { return m_Netname; }

    /**
     * Function GetShortNetname
     * @return const wxString * , a pointer to the short netname
     */
    wxString GetShortNetname() const { return m_ShortNetname; }

    /**
     * Function SetNetname
     * @param const wxString : the new netname
     */
    void SetNetname( const wxString& aNetname );


/**
 * Function DisplayInfo
 * has knowledge about the frame and how and where to put status information
 * about this object into the frame's message panel.
 * Is virtual from EDA_BaseStruct.
 * @param frame A WinEDA_DrawFrame in which to print status information.
 */
    void DisplayInfo( WinEDA_DrawFrame* frame );
};


/****************************************************************/
/* description d'un point de piste pour le suivi des connexions */
/****************************************************************/
#define START_ON_PAD   0x10
#define END_ON_PAD     0x20
#define START_ON_TRACK 0x40
#define END_ON_TRACK   0x80


/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */
enum StatusPcbFlags {
    LISTE_PAD_OK = 1,                           /* Pad list is Ok */
    LISTE_RATSNEST_ITEM_OK = 2,                 /* General Rastnest is Ok */
    RATSNEST_ITEM_LOCAL_OK = 4,                 /* current MODULE rastnest is Ok */
    CONNEXION_OK = 8,                           /* Bit indicant que la liste des connexions existe */
    NET_CODES_OK = 0x10,    /* Bit indicant que les netcodes sont OK ( pas de modif
                             *  de noms de net */
    DO_NOT_SHOW_GENERAL_RASTNEST = 0x20         /* Do not display the general rastnest (used in module moves) */
};


#endif  // __CLASSES_NETINFO__