/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                Copyright (c) 2002-2003 Zanoza Software.                 *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler 2.x user-defined extension helpers
 *--------------------------------------------------------------------------
 * @histroy: 09.02.2009. Created
 */
#ifndef userdefinedhelpers_h_included
#define userdefinedhelpers_h_included

#include <zmodeler.h>
#include <core/ui/controls/IUserDefinedOptions.h>
#include <helpers/controllers.h>
#include <core/ui/controls/IListControl.h>
#include <core/ui/controls/IOptionsColumn.h>
#include <core/io/ISerializeable.h>

namespace core
{

  namespace ui
  {

    namespace controls
    {
      //------------------------------
      //
      //  The user-defined options extension class
      //
      //------------------------------
      class DLL_LINKAGE CUserDefinedOptions : public IUserDefinedOptions,
                                              public core::io::ISerializeable
      {
        public:
          INTERFACE_DECLAREMAP(CUserDefinedOptions)

        public:
          CUserDefinedOptions();
          virtual ~CUserDefinedOptions();

        public:
        //-----------------------
        // IUserDefinedOptions
        //-----------------------
          virtual long getOptionsCount(void);
          virtual ZRESULT deleteOption(long nIndex);
          virtual ZRESULT addOption(ZString strName, 
                                    eOptionControlType type, 
                                    ZString strValue, 
                                    LPCTSTR pszDescription=NULL, 
                                    long* pIndex=NULL);
          virtual ZRESULT addSelectionOption( ZString strName, 
                                              ZStringSeq& seqSelections, 
                                              LPCTSTR strDefault, 
                                              LPCTSTR pszDescription=NULL, 
                                              long* pIndex=NULL);
          virtual ZRESULT getOptionType(long nIndex, eOptionControlType& type);
          virtual ZRESULT setOptionType(long nIndex, eOptionControlType type);
          virtual ZRESULT setOptionName(long nIndex, LPCTSTR pszName);
          virtual ZRESULT getOptionName(long nIndex, ZString& strName);
          virtual ZRESULT setOptionHint(long nIndex, LPCTSTR pszHint);
          virtual ZRESULT getOptionHint(long nIndex, ZString& strHint);
          virtual ZRESULT setOptionValue(long nIndex, LPCTSTR strValue);
          virtual ZRESULT getOptionValue(long nIndex, ZString& strValue);
          virtual ZRESULT getOptionSelections(long nIndex, ZStringSeq& seqSelections);
          virtual ZRESULT getOptionValueByName(LPCTSTR pszName, ZString& strValue);

        public:
        //-----------------------
        // core::io::ISerializeable
        //-----------------------
          virtual ZRESULT saveDeclaration(core::io::IStream* pStream, services::IOpenSaveService* pSrv, LPCTSTR pszResolver=NULL);
          virtual ZRESULT saveData(core::io::IStream* pStream, DWORD dwID, services::IOpenSaveService* pSrv);
          virtual ZRESULT loadData(core::io::IStream* pStream, services::IOpenSaveService* pSrv, DWORD dwSize, DWORD dwVersion=0, bool bMerge=false);
          virtual ZRESULT getReCreationMode(core::io::eReCreationMode& mode);

        private:
        //-----------------------
        // implementation:
        //-----------------------

        private:
        //-----------------------
        // data members:
        //-----------------------
          struct tOptionInfo
          {
            ZString               m_strName;
            ZString               m_strValue;
            ZStringSeq            m_seqSelections;
            ZString               m_strHint;
            eOptionControlType    m_type;
          };
          typedef ZSequence<tOptionInfo>  tOptionInfoSeq;
          tOptionInfoSeq          m_seqOptions;
        public:
        //-----------------------
        // quick accessor. just in case you need it:
        //-----------------------
          inline ZSequence<tOptionInfo>& options() { return m_seqOptions; }
          inline tOptionInfo& getOptionByNameOrCreateNew(LPCTSTR pszName)
          {
            if (pszName)
              for (long n = 0; n < m_seqOptions.length(); n++)
                if (m_seqOptions[n].m_strName && !_tcscmp(m_seqOptions[n].m_strName, pszName))
                  return m_seqOptions[n];
            tOptionInfo& info = m_seqOptions[m_seqOptions.length()];
            info.m_strName = pszName;
            return info;
          }

      };//class


      //
      // helper functions
      //
      DLL_LINKAGE ZRESULT copyUserDefinedOptions(IUserDefinedOptions* pSource, IUserDefinedOptions* pDestination);


      typedef std::map<long, long>      t_UDOOrdinalToIndexMap;
      struct tEmbeddedUDOptionsControl
      {
        WNDPROC                             m_pOldDlgProc;
        class CUserDefinedListController*   m_pController;
        t_UDOOrdinalToIndexMap              m_mapEntries;
      };
      typedef std::map<HWND, ZStdOwnPtr<tEmbeddedUDOptionsControl> > t_UDOControlMap;

      //---------------------------------------------
      //  List controlling helper class.
      //---------------------------------------------
      class DLL_LINKAGE CUserDefinedListController : public core::ui::controls::CListElementController
      {
        public:
          INTERFACE_OVERLOAD_INSTANCE_CREATOR(CUserDefinedListController)

        public:
          CUserDefinedListController();
          virtual ~CUserDefinedListController();

        public:
        //-----------------------
        // IListElementController
        //-----------------------
          virtual ZRESULT onDestroy(void);
          virtual ZRESULT onSetFocus(long nOrdinal);
          virtual ZRESULT onValueChanged(long nOrdinal, ZString& strValue, long nSubItem=0);

        public:
        //---------------------------------
        //  Accessors
        //---------------------------------
          ZRESULT synchronizeList(core::ui::controls::IUserDefinedOptions* pOptions);
          ZRESULT embedList(CWnd* pContainer, 
                            UINT nListID, 
                            UINT nDelButtonID = 0xFFFF, 
                            UINT nAddButtonID = 0xFFFF, 
                            UINT nAddEdit = 0xFFFF);
        private:
          static t_UDOControlMap                          m_mapUDOControllers;
          static LRESULT CALLBACK UDOControlWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
        private:
          ZPtr<core::ui::controls::IListControl>          m_pList;
          ZPtr<core::ui::controls::IOptionsColumn>        m_pListOptions;
          ZPtr<core::ui::controls::IUserDefinedOptions>   m_pOptions;
          UINT          m_nIDList, m_nIDDel, m_nIDAdd, m_nIDEdit;

      };//class

    };//controls


  };//ui

};//core

#endif //userdefinedhelpers_h_included

