/////////////////////////////////////////////////////////////////////////////
// Name:        packageinfo.h
// Purpose:     wxPackageInfo
// Author:      Julian Smart, Francesco Montorsi, Daniel J. Lauk
// Modified by:
// Created:     2004-11-07
// RCS-ID:      $Id: packageinfo.h,v 1.18 2007/01/31 13:27:46 frm Exp $
// Copyright:   (c) Julian Smart, Francesco Montorsi, Daniel J. Lauk
// Licence:     wxWidgets licence
/////////////////////////////////////////////////////////////////////////////

#ifndef _PACKAGEINFO_H_
#define _PACKAGEINFO_H_

// Includes
#include "wx/download.h"
#include "wx/xml/xml.h"
#include "wx/tokenzr.h"
#include "wx/filefn.h"
#include "wx/filesys.h"

#include "wxp/packageutils.h"
#include "wxp/packagecmd.h"
#include "wxp/packagedep.h"

// forward declarations
class wxConfigBase;
class wxPackage;
class wxPackageArray;
class wxFFileInputStream;
class wxPackageCommandSet;



// ----------------------------------------------------------------------------
// enums
// ----------------------------------------------------------------------------

//! The possible categories for a wxPackage.
//! NB: keep them in alphabetic order.
enum wxPackageCategory
{
    wxPC_INVALID = -1,

    wxPC_APPLICATION,
    wxPC_CONTROL,
    wxPC_DIALOG,
    wxPC_DATABASE,
    wxPC_DATACONTAINER,
    wxPC_GRAPHICS,
    wxPC_IMPORTEXPORT,
    wxPC_MISCELLANEOUS,
    wxPC_NETWORKING,
    wxPC_PRINTING,
    wxPC_STREAM,
    wxPC_SYSTEM,
    wxPC_TEXTPROCESSING,
    wxPC_TUTORIALDOC,
    wxPC_WINDOWCONTAINER,
    wxPC_WINDOWLAYOUT,
    wxPC_WRAPPER,
    wxPC_XRC,

    wxPC_MAX
};

//! The possible types of license of a wxPackage.
enum wxPackageLicenseType
{
    wxPLT_INVALID = -1,

    wxPLT_OPENSOURCE,
    wxPLT_COMMERCIAL,
    wxPLT_SHAREWARE,
    wxPLT_FREEWARE,
    wxPLT_OTHER,

    wxPLT_MAX
};

//! The possible development stages of a wxPackage.
enum wxPackageDevelopmentStatus
{
    wxPDS_INVALID = -1,

    wxPDS_ALPHA,
    wxPDS_BETA,
    wxPDS_STABLE,

    wxPDS_MAX
};

//! The possible programming languages of the source code of a wxPackage.
enum wxPackageProgLanguage
{
    wxPPL_INVALID = -1,

    wxPPL_CPP,
    wxPPL_LUA,
    wxPPL_PYTHON,
    wxPPL_RUBY,
    wxPPL_PERL,

    wxPPL_MAX
};

//! The possible formats used to compress a wxPackage.
enum wxPackageCompressionMode
{
    wxPCM_INVALID = -1,

    wxPCM_ZIP,
    wxPCM_TAR_GZ,

    wxPCM_MAX
};

//! The possible ways to indicate something to be excluded
//! when the package must be compressed.
enum wxPackageExcludeMode
{
    wxPEM_INVALID = -1,

    wxPEM_FILE,
    wxPEM_DIRECTORY,
    wxPEM_PATTERN,

    wxPEM_MAX
};

wxDEFINE_STRING2ENUM(PackageCategory)
wxDEFINE_STRING2ENUM(PackageLicenseType)
wxDEFINE_STRING2ENUM(PackageDevelopmentStatus)
wxDEFINE_STRING2ENUM(PackageProgLanguage)
wxDEFINE_STRING2ENUM(PackageCompressionMode)
wxDEFINE_STRING2ENUM(PackageExcludeMode)

// the compression levels for the compression formats defined above
#define wxPKG_TARGZ_COMPRESSION_LEVEL     wxZ_BEST_COMPRESSION
#define wxPKG_ZIP_COMPRESSION_LEVEL       8 /* in 0-9 range where 9 is best compression */

// the flags accepted by wxPackageInfo::GetSubstCmdForStage
enum
{
    // substitute only the options whose value differs from the default value
    wxPKGCMD_ONLY_CHANGED = 2,

    // substitute only the options which "match" (see wxPackageCondition::Matches)
    // a particular wxPackageCondition
    wxPKGCMD_ONLY_MATCHING_CONDITION = 4
};



// ----------------------------------------------------------------------------
// wxPackageInfo
// ----------------------------------------------------------------------------

//! Holds all information about a wxWidgets package and all getters/setters
//! required to access/change them. No higher-level functions.
//! See wxPackage for them.
class wxPackageInfo : public wxPackageId
{
    friend class wxPackageArray;
    DECLARE_DYNAMIC_CLASS(wxPackageInfo)

public:

    //! Default constructor.
    wxPackageInfo();

    //! Default destructor.
    virtual ~wxPackageInfo() {}


public:     // misc
/*
    bool operator== (const wxPackageInfo& package) const;
    bool operator!= (const wxPackageInfo& package) const
        { return !(*this == package); }
*/
    // just a simple function to write more readable code
    bool HasSameIdOf(const wxPackageInfo &pkg) const
        { return ((const wxPackageId &)*this) == ((const wxPackageId &)pkg); }

public:     // static

    static wxPackageHTMLOutputFormatHashMap s_hashmapHTMLFormats;

    //! Loads the standard output formats of wxPackage API.
    static bool LoadStandardOutputFormats(const wxString &dirbase);

public:    // BASICS getters

    wxString GetDescription() const { return m_strDescription; }
    wxArrayString GetKeywords() const { return m_arrKeywords; }
    wxString GetKeywordsStr() const { return wxArray2String(m_arrKeywords, wxT(", ")); }
    wxString GetWebsite() const { return m_strWebsite; }
    wxDateTime GetCreationDate() const { return m_creationDate; }

    wxPackageCategory GetPrimaryCategory() const { return m_catPrimary; }
    wxPackageCategory GetSecondaryCategory() const { return m_catSecondary; }

    wxString GetPrimaryCategoryStr() const
        { return wxPackageCategory2String(GetPrimaryCategory()); }
    wxString GetSecondaryCategoryStr() const
        { return wxPackageCategory2String(GetSecondaryCategory()); }

public:     // PACKAGING getters

    wxString GetRelativeRoot() const { return m_strRoot; }
    wxString GetOutputFileName() const { return m_strFileName; }
    wxArrayString GetExcluded(wxPackageExcludeMode type) const
        { return m_arrExcluded[type]; }
    wxPackageCompressionMode GetCompressionMode() const { return m_compressMode; }

    wxString GetCompressionModeStr() const
        { return wxPackageCompressionMode2String(m_compressMode); }

    wxString GetUploadDestination() const
        { return m_strUpload; }

    // not a simple getter: given the ABSOLUTE path of the WXP location, it returns
    // the (absolute) project folder.
    wxString GetProjectFolder(const wxString &wxppath) const;

public:     // DETAILS getters

    wxPackageBuildSystemType GetBuildSystemType() const
        { return m_buildSystemType; }
    wxPackageDevelopmentStatus GetDevelopmentStatus() const
        { return m_devStatus; }
    wxPackageProgLanguage GetProgLanguage() const
        { return m_language; }

    wxString GetBuildSystemTypeStr() const
        { return wxPackageBuildSystemType2String(GetBuildSystemType()); }
    wxString GetDevelopmentStatusStr() const
        { return wxPackageDevelopmentStatus2String(GetDevelopmentStatus()); }
    wxString GetProgLanguageStr() const
        { return wxPackageProgLanguage2String(GetProgLanguage()); }

    wxString GetRSSHref() const
        { return m_strRSSHref; }

    wxArrayString GetDownloadHref() const
        { return m_arrDownloadHref; }
    wxString GetDownloadHref(size_t n) const
        { return SubstituteInfo(m_arrDownloadHref[n]); }
    wxString GetRepoDownloadLink() const
        { return SubstituteInfo(m_strDownloadFromRepoHref); }

    // not a trivial getter: returns the URL to use when you want to
    // download this package. It gives priority to the repo download
    // link and, if this is not available, chooses a random mirror
    // from the download href array:
    wxString GetDownloadLink() const;

    wxPackageDataWithRef GetLogoRef() const
        { return m_refLogo; }

    wxPackageDataWithRefArray GetDocumentation() const
        { return m_arrDocumentation; }
    wxPackageDataWithRef GetDocumentation(size_t n) const
        { return m_arrDocumentation[n]; }
    wxPackageDataWithRefArray GetScreenshots() const
        { return m_arrScreenshots; }
    wxPackageDataWithRef GetScreenshot(size_t n) const
       { return m_arrScreenshots[n]; }

    size_t GetNumberOfSamples() const
        { return m_nSamples; }
    wxULongLong GetCompressedSize() const
        { return m_nCompressedSize; }

    wxString GetMD5() const
        { return m_strMD5; }

public:     // LICENSING getters

    wxPackageDataWithRef GetLicenseRef() const { return m_refLicense; }
    wxString GetLicenseTypeStr() const
        { return wxPackageLicenseType2String(GetLicenseType()); }
    wxPackageLicenseType GetLicenseType() const { return m_nLicenseType; }

    wxString GetOrganization() const { return m_strOrganization; }
    wxString GetOrganizationHref() const { return m_strOrganizationHref; }

    wxString GetCost() const { return m_strCost; }

    wxArrayString GetAuthors() const { return m_arrAuthorName; }
    wxArrayString GetAuthorsHref() const { return m_arrAuthorHref; }
    wxArrayString GetMaintainers() const { return m_arrMaintainerName; }
    wxArrayString GetMaintainersHref() const { return m_arrMaintainerHref; }

    wxString GetCredits() const { return m_strCredits; }
    wxString GetCopyright() const { return m_strCopyright; }

public:     // DEPENDENCIES getters

    long GetSupportedPortFlag() const
    {
        long ret = 0;
        for (size_t i=0; i < m_arrSupportedPort.GetCount(); i++)
            ret |= m_arrSupportedPort[i];
        return ret;
    }

    long GetTestedPortFlag() const
    {
        long ret = 0;
        for (size_t i=0; i < m_arrTestedPort.GetCount(); i++)
            ret |= m_arrTestedPort[i];
        return ret;
    }

    wxArrayInt GetSupportedPorts() const
        { return m_arrSupportedPort; }
    wxArrayInt GetTestedPorts() const
        { return m_arrTestedPort; }
    wxVersionRangeArray GetSupportedVersions() const
        { return m_arrSupportedVersion; }
    wxVersionRangeArray GetTestedVersions() const
        { return m_arrTestedVersion; }

    wxPackageDependencyArray GetDependencies() const
        { return m_arrDependencies; }

    bool SupportsWxPort(wxPortId p, const wxVersion &ver) const;

    bool HasSameSupportedPortVersions() const
    {
        for (size_t i=0; i < m_arrSupportedPort.GetCount() - 1; i++)
            if (m_arrSupportedVersion[i] != m_arrSupportedVersion[i+1])
                return false;
        return true;
    }

    bool HasSameTestedPortVersions() const
    {
        for (size_t i=0; i < m_arrTestedPort.GetCount() - 1; i++)
            if (m_arrTestedVersion[i] != m_arrTestedVersion[i+1])
                return false;
        return true;
    }

public:     // BUILD SYSTEM getters

    // provide both const and non-const overloads of the getters:

    wxPackageCommandArray &GetCmdForStage(wxPackageBuildSystemStage stage)
        { return m_arrCommands[wxPackageBuildSystemStage2Idx(stage)]; }
    const wxPackageCommandArray &GetCmdForStage(wxPackageBuildSystemStage stage) const
        { return m_arrCommands[wxPackageBuildSystemStage2Idx(stage)]; }

    wxPackageCommandOptionArray &GetBuildSysOptions()
        { return m_opt; }
    const wxPackageCommandOptionArray &GetBuildSysOptions() const
        { return m_opt; }

    long GetSupportedBuildSysFormats() const
        { return m_nSupportedFormats; }
    wxString GetBuildSystemHref() const
        { return m_strBuildSystemHref; }


    // non-trivial (i.e. not-inlined) getters:

    //! Returns the array of commands for the given stage.
    //! The wxPKGCMD_* flags define which operations should be done on the
    //! array before returning it.
    wxPackageCommandArray 
        GetSubstCmdForStage(wxPackageBuildSystemStage stage,
                            long flags,
                            const wxPackageCondition &cond = 
                                    wxEmptyPackageCondition) const;

    //! Returns the array of options for this package with the default and the
    //! selected values substituted.
    wxPackageCommandOptionArray GetSubstBuildSysOptions() const;

    //! Returns true if this package supports the given compiler format.
    bool SupportsBuildSysFormat(wxPackageCompilerFormat fmt) const;

    //! Returns the names of the option presets used by this package or an
    //! empty array if no option presets are used.
    wxArrayString GetUsedOptionPresets() const;

    //! Returns the name (multiple command presets are not supported) of the
    //! command preset used by this package or wxEmptyString if no command presets
    //! are in use.
    //! When returning a non-empty string, the given hashmap is filled with the
    //! names & values of the command presets' variables used by this package.
    wxString GetUsedCommandPreset(wxStringHashMap &h) const;

public:     // BASICS setters

    void SetDescription(const wxString &str)
        { m_strDescription=str; }

    void SetKeywords(const wxString &str)
    { 
        m_arrKeywords=wxString2Array(str, wxT(',')); 
        for (size_t i=0; i<m_arrKeywords.GetCount(); i++)
            m_arrKeywords[i] = m_arrKeywords[i].Strip(wxString::both);
    }
    void SetKeywords(const wxArrayString &arr)
        { m_arrKeywords=arr; }

    void SetWebsite(const wxString &str)
        { m_strWebsite=str; }
    void SetCreationDate(const wxDateTime &date)
        { m_creationDate=date; }
    void SetCreationDate(const wxString &str)
        { m_creationDate.ParseDate(str); }

    void SetCategories(wxPackageCategory primary, wxPackageCategory secondary)
        { m_catPrimary=primary; m_catSecondary=secondary; }

    void SetPrimaryCategoryStr(const wxString &str)
        { m_catPrimary = wxString2PackageCategory(str); }
    void SetSecondaryCategoryStr(const wxString &str)
        { m_catSecondary = wxString2PackageCategory(str); }

public:     // PACKAGING setters

    void SetRoot(const wxString &root)
        { m_strRoot=root; }
    void SetFileName(const wxString &filename)
        { m_strFileName=filename; } 

    void SetExcluded(wxPackageExcludeMode mode,
                     const wxArrayString &arr)
    { 
        m_arrExcluded[mode]=arr; 
    }

    void SetCompressionMode(wxPackageCompressionMode mode)
        { m_compressMode=mode; }
    void SetCompressModeStr(const wxString &str)
        { m_compressMode=wxString2PackageCompressionMode(str); }

    void SetUploadDestination(const wxString &str)
        { m_strUpload=str; }

public:     // LICENSING setters

    void SetLicenseRef(const wxPackageDataWithRef &ref)
        { m_refLicense=ref; }
    void SetLicenseType(wxPackageLicenseType t)
        { m_nLicenseType=t; }
    void SetLicenseTypeStr(const wxString &str)
        { m_nLicenseType=wxString2PackageLicenseType(str); }

    void SetOrganization(const wxString &str, const wxString &href)
        { m_strOrganization=str; m_strOrganizationHref=href; }

    void SetCost(const wxString &str)
        { m_strCost=str; }
    void SetCredits(const wxString &str)
        { m_strCredits=str; }
    void SetCopyright(const wxString &str)
        { m_strCopyright=str; }

    void SetAuthors(const wxArrayString &name, const wxArrayString &href)
        { m_arrAuthorName=name; m_arrAuthorHref=href; }
    void AddAuthor(const wxString &name, const wxString &href)
        { m_arrAuthorName.Add(name); m_arrAuthorHref.Add(href); }

    void SetMaintainers(const wxArrayString &name, const wxArrayString &href)
        { m_arrMaintainerName=name; m_arrMaintainerHref=href; }
    void AddMaintainer(const wxString &name, const wxString &href)
        { m_arrMaintainerName.Add(name); m_arrMaintainerHref.Add(href); }

public:     // DETAILS setters

    void SetDevelopmentStatus(wxPackageDevelopmentStatus t)
        { m_devStatus=t; }
    void SetDevelopmentStatusStr(const wxString &str)
        { m_devStatus=wxString2PackageDevelopmentStatus(str); }

    void SetProgLanguage(wxPackageProgLanguage t)
        { m_language=t; }
    void SetProgLanguageStr(const wxString &str)
        { m_language=wxString2PackageProgLanguage(str); }

    void SetRSSHref(const wxString &str)
        { m_strRSSHref=str; }
    void AddMirror(const wxString &href)
        { m_arrDownloadHref.Add(href); }

    void SetRepoDownloadLink(const wxString &href)
        { m_strDownloadFromRepoHref=href; }

    // href & localref management
    void AddDoc(const wxPackageDataWithRef &ref)
        { m_arrDocumentation.Add(ref); }
    void AddDoc(const wxString &type, const wxString &href, const wxString &localref)
        { m_arrDocumentation.Add(wxPackageDataWithRef(type, href, localref)); }

    void AddScreenshot(const wxPackageDataWithRef &ref)
        { m_arrScreenshots.Add(ref); }
    void AddScreenshot(const wxString &href, const wxString &localref)
        { m_arrScreenshots.Add(wxPackageDataWithRef(href, href, localref)); }

    void SetLogoRef(const wxPackageDataWithRef &ref)
        { m_refLogo=ref; }
    void SetLogo(const wxString &href, const wxString &localref)
        { m_refLogo.SetHref(href); m_refLogo.SetLocalRef(localref); }
    void SetNumberOfSamples(size_t n)
        { m_nSamples=n; }
    void SetCompressedSize(wxULongLong n)
        { m_nCompressedSize=n; }
    void SetMD5(const wxString &md5)
        { m_strMD5=md5; }

public:     // DEPENDENCIES setters

    void AddSupportedPort(wxPortId port, const wxVersionRange &version)
    {
        if (port != wxPORT_UNKNOWN)
        {
            m_arrSupportedPort.Add(port);
            m_arrSupportedVersion.Add(version);
        }
    }

    void AddTestedPort(wxPortId port, const wxVersionRange &version)
    {
        if (port != wxPORT_UNKNOWN)
        {
            m_arrTestedPort.Add(port);
            m_arrTestedVersion.Add(version);
        }
    }

    void AddSupportedPort(const wxString &port, const wxVersionRange &version)
        { AddSupportedPort(wxPlatformInfo::GetPortId(port), version); }
    void AddTestedPort(const wxString &port, const wxVersionRange &version)
        { AddTestedPort(wxPlatformInfo::GetPortId(port), version); }

    void SetSupportedPorts(const wxArrayInt &port, const wxVersionRangeArray &version)
    {
        wxASSERT(port.GetCount() == version.GetCount());
        m_arrSupportedPort.Clear();
        m_arrSupportedVersion.Clear();
        for (size_t i=0; i<port.GetCount(); i++)
            AddSupportedPort((wxPortId)port[i], version[i]);
    }

    void SetTestedPorts(const wxArrayInt &port, const wxVersionRangeArray &version)
    {
        wxASSERT(port.GetCount() == version.GetCount());
        m_arrTestedPort.Clear();
        m_arrTestedVersion.Clear();
        for (size_t i=0; i<port.GetCount(); i++)
            AddTestedPort((wxPortId)port[i], version[i]);
    }

    void AddDependency(const wxPackageDependency &toadd)
        { m_arrDependencies.Add(toadd); m_arrDependencies.Last().SetOwnerId(*this); }

    void SetDependencies(const wxPackageDependencyArray &arr)
    {
        m_arrDependencies = arr;
        for (size_t i=0; i<arr.GetCount(); i++)
            m_arrDependencies[i].SetOwnerId(*this);
    }

public:     // BUILD SYSTEM setters


    void AddBuildSysOption(const wxPackageCommandOption &opt)
        { m_opt.Add(opt); }
    void AddBuildSysOptions(const wxPackageCommandOptionArray &arr)
    {
        for (size_t j=0; j<arr.GetCount(); j++)
            AddBuildSysOption(arr[j]);
    }

    void AddBuildSysCommand(long stages, const wxPackageCommand &cmd);
    void AddBuildSysCommands(const wxPackageCommandArray &arr);

    void SetBuildSysOptions(const wxPackageCommandOptionArray &arr)
        { m_opt=arr; }
    void SetBuildSysCommands(wxPackageBuildSystemStage stage, const wxPackageCommandArray &arr)
        { m_arrCommands[wxPackageBuildSystemStage2Idx(stage)]=arr; }

    void SetBuildSysHref(const wxString &href)
        { m_strBuildSystemHref=href; }

    void SetBuildSystemType(wxPackageBuildSystemType t)
        { m_buildSystemType=t; }
    void SetBuildSystemTypeStr(const wxString &str)
        { m_buildSystemType=wxString2PackageBuildSystemType(str); }

    void SetSupportedFormats(long n)
        { m_nSupportedFormats=n; }

public:     // misc utilities

    bool IsOk() const;

    //! Substitutes various keywords (e.g. $(version), $(name), etc) in the
    //! given string and then returns it.
    //! Note that to be sure the substituted infos are up2date with package's info,
    //! you need to call the (time-consuming) #UpdateSubstitutionHashMap function first.
    virtual wxString SubstituteInfo(const wxString &str,
                                    wxPackageSubstituteInfoContext ctx = wxPSIC_WXHTML) const;

    //! Rebuilds the #m_hashmapSubstitution hash tables will all infos to substitute
    //! for the given context. Rebuilds all tables if wxPSIC_INVALID is given.
    void UpdateSubstitutionHashMap(wxPackageSubstituteInfoContext ctx = wxPSIC_INVALID);

    //! Returns the substitution hashmap for the given context.
    wxStringHashMap GetSubstitutionHashMap(wxPackageSubstituteInfoContext ctx) const
        { return m_hashmapSubstitution[ctx]; }

    //! Returns true if the substitution hashmap is updated with all current values
    //! of the info stored in this wxPackageInfo object:
    bool IsCachedSubstitutionHashMapValid(wxPackageSubstituteInfoContext ctx) const
        { return !m_hashmapSubstitution[ctx].empty(); }

    //! Invalidates the substitution hashmap cache forcing an update on the next
    //! call to #SubstituteInfo.
    //! Invalidates all hashmaps if wxPSIC_INVALID is given.
    void InvalidateCachedSubstHashMap(wxPackageSubstituteInfoContext ctx = wxPSIC_INVALID);

public:         // static substitutions

    //! A static, i.e. global, set of keywords and relative values which are
    //! substituted by #SubstituteStandard.
    static wxStringHashMap s_hashmapKeywords;

    //! Returns the standard substitution hashmap: i.e. the #s_hashmapKeywords
    //! hashmap merged with some standard constant keys.
    static wxStringHashMap GetStandardSubstitutionHashMap();

    //! Returns the given string with some standard strings (e.g. $(MAKE), etc)
    //! substituted by their constant values.
    static wxString SubstituteStandard(const wxString &str)
        { return wxDoStringSubstitution(str, GetStandardSubstitutionHashMap()); }

protected:      // misc utilities

    //! See #UpdateSubstitutionHashMap for more info.
    virtual void DoUpdateSubstitutionHashMap(wxPackageSubstituteInfoContext ctx);

    //! Uses the current option values and the given stage to substitute variables
    //! inside the given wxPackageCommand and then returns it.
    virtual wxPackageCommand GetCmd(const wxPackageCommand &cmd, 
                                    wxPackageBuildSystemStage stage,
                                    long flags,
                                    const wxPackageCondition &cond) const;

protected:      // BASICS

    wxArrayString m_arrKeywords;
    wxString m_strDescription;
    wxString m_strWebsite;
    wxDateTime m_creationDate;

    wxPackageCategory m_catPrimary, m_catSecondary;

protected:      // PACKAGING

    wxString m_strRoot;
    wxString m_strFileName;
    wxString m_strUpload;

    wxArrayString m_arrExcluded[wxPEM_MAX];
    wxPackageCompressionMode m_compressMode;

protected:      // LICENSING

    wxPackageDataWithRef m_refLicense;
    wxPackageLicenseType m_nLicenseType;

    wxString m_strOrganization, m_strOrganizationHref;
    wxString m_strCost;

    wxArrayString m_arrAuthorName, m_arrAuthorHref;
    wxArrayString m_arrMaintainerName, m_arrMaintainerHref;

    wxString m_strCredits;
    wxString m_strCopyright;

protected:      // DETAILS

    wxPackageDevelopmentStatus m_devStatus;
    wxPackageProgLanguage m_language;

    wxString m_strRSSHref;
    wxArrayString m_arrDownloadHref;

    // the repository download link: this is the URL to use when downloading
    // a package which is part of a repository.
    // NOTE: this info is not part of the WXP description file
    //       but rather of the WXL repository descriptor: thus it's
    //       set only when this wxPackageInfo has been created when
    //       parsing a WXL file.
    wxString m_strDownloadFromRepoHref;

    // these can have both an href and a localref
    wxPackageDataWithRef m_refLogo;
    wxPackageDataWithRefArray m_arrDocumentation;
    wxPackageDataWithRefArray m_arrScreenshots;

    size_t m_nSamples;

    // the size, in bytes, of the WXZ for this package or 0
    // if not available.
    wxULongLong m_nCompressedSize;

    // the MD5 checksum
    // NOTE: this info is not part of the WXP description file
    //       but rather of the WXL repository descriptor: thus it's
    //       set only when this wxPackageInfo has been created when
    //       parsing a WXL file.
    wxString m_strMD5;

protected:      // DEPENDENCIES

    wxVersionRangeArray m_arrSupportedVersion, m_arrTestedVersion;

    // WARNING: cannot use a simple flag here which contains
    //          combined values of supported/tested ports as
    //          in that case we could not understand which
    //          version is supported by which port.
    wxArrayInt m_arrSupportedPort, m_arrTestedPort;

    // inter-packages dependencies
    wxPackageDependencyArray m_arrDependencies;

protected:      // BUILD SYSTEM

    //! The build system supported by this package.
    wxPackageBuildSystemType m_buildSystemType;

    //! The local reference to the build system's main file of this package.
    //! This is a localref to a .bkl file for Bakefile, to a CMakeLists.txt
    //! for CMake and to an SConstruct file for Scons.
    //! NOTE: this info is (at least currently) unused by wxWPM tools but
    //!       it may still be useful to have it for e.g. other tools which
    //!       want/need to parse WXP files.
    wxString m_strBuildSystemHref;

    //! The wxPackageCompilerFormats supported by this package
    //! for the build system m_buildSystemType.
    long m_nSupportedFormats;

    //! The options for the build system stages of this package.
    wxPackageCommandOptionArray m_opt;

    //! The array of commands for the various stages of this package.
    //! Each command is associated with a wxPackageCondition which specifies
    //! to which stage it applies and for which format, etc.
    wxPackageCommandArray m_arrCommands[wxPBSS_MAX];

protected:     // OTHERS

    //! The hashmap containing the keys & relative values for substitution.
    //! See UpdateSubstitutionHashMap for more info.
    wxStringHashMap m_hashmapSubstitution[wxPSIC_MAX];
};

#endif      // _PACKAGEINFO_H_

