// genpage.cpp : implementation file
//

#include "precomp.hxx"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGeneralPage property page

IMPLEMENT_DYNCREATE(CGeneralPage, CPropertyPage)

CGeneralPage::CGeneralPage() : CPropertyPage(CGeneralPage::IDD)
{
    //{{AFX_DATA_INIT(CGeneralPage)
    m_szName = _T("");
    m_szDeploy = _T("");
    m_szDescription = _T("");
    m_szLocale = _T("");
    m_szPath = _T("");
    m_szVer = _T("");
    m_fShow = TRUE;
    //}}AFX_DATA_INIT

    m_hConsoleHandle = NULL;
    m_bUpdate = FALSE;
}

CGeneralPage::~CGeneralPage()
{
}

void CGeneralPage::DoDataExchange(CDataExchange* pDX)
{
    CPropertyPage::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CGeneralPage)
    DDX_Control(pDX, IDC_DEPLOY, m_cbDeploy);
    DDX_CBString(pDX, IDC_DEPLOY, m_szDeploy);
    DDX_Text(pDX, IDC_NAME, m_szName);
    DDX_Text(pDX, IDC_DESCRIPTION, m_szDescription);
    DDX_Text(pDX, IDC_LOCALE, m_szLocale);
    DDX_Text(pDX, IDC_PATH, m_szPath);
    DDX_Text(pDX, IDC_VERSION, m_szVer);
    DDX_Control(pDX, IDC_CPU, m_cbCPU);
    DDX_Control(pDX, IDC_OS, m_cbOS);
    DDX_Check(pDX, IDC_CHECK1, m_fShow);
    //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CGeneralPage, CPropertyPage)
    //{{AFX_MSG_MAP(CGeneralPage)
    ON_WM_DESTROY()
    ON_EN_CHANGE(IDC_NAME, OnChangeName)
    ON_EN_CHANGE(IDC_PATH, OnChangePath)
    ON_EN_CHANGE(IDC_DESCRIPTION, OnChangeDescription)
    ON_BN_CLICKED(IDC_CHECK1, OnChangeShow)
    ON_CBN_SELCHANGE(IDC_DEPLOY, OnSelchangeDeploy)
    ON_CBN_SELCHANGE(IDC_OS, OnChangeOS)
    ON_CBN_SELCHANGE(IDC_CPU, OnChangeCPU)
    ON_EN_CHANGE(IDC_VERSION, OnChangeVersion)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CGeneralPage::OnApply()
{
#if 0
    if (m_pIAppManagerActions == NULL || m_pIClassAdmin == NULL)
    {
        return FALSE;
    }
    // put up an hourglass (this could take a while)
    CHourglass hourglass;

    CString szNewScriptPath;
    CString szOldScriptPath;

    HRESULT hr;
    if (m_bUpdate == TRUE)
    {
        PACKAGEDETAIL NewDetails;
        hr = m_pIClassAdmin->GetPackageDetails(m_pData->szName,
            &NewDetails.InstallInfo,
            &NewDetails.PlatformInfo);
        memcpy(&NewDetails, m_pData->pDetails, sizeof(PACKAGEDETAIL));

        // UNDONE - validate the data

        NewDetails.pszPackageName = (LPOLESTR) ((LPCTSTR)m_szName);

        swscanf((LPOLESTR)((LPCTSTR)m_szVer), _T("%u.%u"),&(NewDetails.Platform.dwVersionHi),&(NewDetails.Platform.dwVersionLo));
        NewDetails.Platform.dwPlatformId = m_cbOS.GetCurSel();
        NewDetails.Platform.dwProcessorArch = m_cbCPU.GetCurSel() == 1 ? PROCESSOR_ARCHITECTURE_ALPHA : PROCESSOR_ARCHITECTURE_INTEL;

        NewDetails.dwActFlags = (m_pData->pDetails->dwActFlags & (! (ACTFLG_Published | ACTFLG_Assigned | ACTFLG_UserInstall)));
        BOOL fAssign = FALSE;
        if (m_szDeploy == m_szPublished)
        {
            NewDetails.dwActFlags |= ACTFLG_Published;
        }
        else
        {
            NewDetails.dwActFlags |= ACTFLG_Assigned;
            fAssign = TRUE;
        }

        NewDetails.dwActFlags |= ((!m_fShow) ? 0 : ACTFLG_UserInstall);
        BOOL fMoveScript = (NewDetails.dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
            != (m_pData->pDetails->dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
            || (NewDetails.Platform.dwProcessorArch != m_pData->pDetails->Platform.dwProcessorArch);
        if (fMoveScript)
        {
            // Find out if script file can in fact be moved
            BOOL fCanMoveScript = FALSE;

            szOldScriptPath = m_pData->szPath;
            CString szTemp = szOldScriptPath;
            szTemp.MakeLower();
            int i = szTemp.Find(_T("\\published\\"));
            if (i < 0)
            {
                i = szTemp.Find(_T("\\assigned\\")); // cover all the bases
            }
            if (i >= 0)
            {
                // finally make sure it's got an .aas extension
                if (szTemp.Right(4) == _T(".aas"))
                {
                    DWORD dwAttributes =  GetFileAttributes(m_pData->szPath);
                    if ((dwAttributes != 0xffffffff) && ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0))
                    {
                        fCanMoveScript = TRUE;
                    }
                }
            }
            if (fCanMoveScript)
            {
                // Build new path

                szNewScriptPath = szOldScriptPath;
                // Strip off everything up to "\\published" or "\\assigned"
                szNewScriptPath = szNewScriptPath.Left(i);
                szNewScriptPath +=
                    (NewDetails.dwActFlags & ACTFLG_Assigned) != 0
                    ? _T("\\Assigned") : _T("\\Published");
                szNewScriptPath +=
                    NewDetails.Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA
                    ? _T("\\Alpha\\") : _T("\\x86\\");
                {
                    TCHAR Name [_MAX_FNAME];
                    TCHAR Ext [_MAX_EXT];
                    TCHAR ScriptNameAndPath[_MAX_PATH ];
                    _tsplitpath( szOldScriptPath, NULL, NULL, Name, Ext );

                    szNewScriptPath += Name;
                    szNewScriptPath += Ext;
                }

                // Try and move it

                if (!MoveFileEx(szOldScriptPath,
                                szNewScriptPath,
                                MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
                {
                    // wasn't moved
                    fMoveScript = FALSE;

                    // UNDONE - put up a message that the scrip file wasn't moved?
                }
                else
                {
                    m_pData->szPath = szNewScriptPath;
                    NewDetails.pszScriptPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
                }
            }
            else
            {
                // wasn't moved so make sure we don't try and move it back later
                fMoveScript = FALSE;
            }
        }

        NewDetails.pszProductName = (LPOLESTR) ((LPCTSTR)m_szDescription);

        BOOL fPathChanged = m_szPath != m_pData->szPath;
        if (fPathChanged)
        {
            // user changed the path
            NewDetails.pszScriptPath = (LPOLESTR)((LPCTSTR)m_szPath);
        }


        hr = m_pIClassAdmin->DeletePackage(m_pData->pDetails->pszPackageName);
        if (SUCCEEDED(hr))
        {
            hr = m_pIClassAdmin->AddPackage(m_szName, &NewDetails);
        }
        if (FAILED(hr))
        {
            if (fMoveScript)
            {
                // changed location for deployment back to what it was
                // before we failed to change the info in the class store
                // (Note that we're assuming that if we could change it one way
                // we can change it back.)

                if (MoveFileEx(szNewScriptPath,
                               szOldScriptPath,
                               MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
                {
                    m_pData->szPath = szOldScriptPath;
                    m_pData->pDetails->pszScriptPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
                }

            }
            hr = m_pIClassAdmin->AddPackage(m_szName, m_pData->pDetails);
            // need to move this message
            ::MessageBox(NULL,
                         L"Couldn't apply changes.  Verify that the class store's server is active.",
                         L"ERROR",
                         MB_OK);
            return FALSE;
        }
        else
        {
            if (fMoveScript)
            {
                // Notify clients of change
                if (m_pIAppManagerActions)
                {
                    m_pIAppManagerActions->NotifyClients(FALSE);
                }
            }
        }

        memcpy(m_pData->pDetails, &NewDetails, sizeof(PACKAGEDETAIL));
        if (m_pData->pDetails->dwActFlags & ACTFLG_Assigned)
        {
            m_pData->type = DT_ASSIGNED;
        }
        else
        {
            m_pData->type = DT_PUBLISHED;
        }
        m_pData->szType = m_szDeploy;
        // Up above, we set NewDetails.pszPackageName to m_szName.
        // We can't leave it set to that because m_szName is a member
        // variable of this property sheet class object and will be released
        // when the property sheet goes away.  We need to copy it to
        // m_pData->szName (which is a CString and therefore has it's own
        // memory store) and then set the details back to it so it doesn't
        // get freed from under us.
        m_pData->szName = m_szName;
        m_pData->pDetails->pszPackageName = (LPOLESTR)((LPCTSTR)m_pData->szName);
        // same problem with szDesc
        m_pData->szDesc = m_szDescription;
        m_pData->pDetails->pszProductName = (LPOLESTR)((LPCTSTR)m_pData->szDesc);
        if (fPathChanged)
        {
            m_pData->szPath = m_szPath;
            m_pData->pDetails->pszScriptPath = (LPOLESTR)((LPCTSTR)m_pData->szPath);
        }
        if (m_szPath != m_pData->szPath)
        {
            // user changed the path
            m_pData->szPath = m_szPath;
            m_pData->pDetails->pszScriptPath = (LPOLESTR)((LPCTSTR)m_pData->szPath);
        }

        SetStringData(m_pData);

        MMCPropertyChangeNotify(m_hConsoleHandle, (long) m_cookie);

        m_bUpdate = FALSE;
    }
#endif
    return CPropertyPage::OnApply();
}

BOOL CGeneralPage::OnInitDialog()
{
    TCHAR szBuffer[256];
    m_szName = m_pData->pDetails->pszPackageName;
    m_szDescription = _T("");
    m_szLocale = _T("");
    m_szPath = m_pData->pDetails->pInstallInfo->pszScriptPath;
    m_szDeploy = _T("");
    // wsprintf(szBuffer, _T("%u.%u"), m_pData->pDetails->Platform.dwVersionHi, m_pData->pDetails->Platform.dwVersionLo);
    m_szVer = szBuffer;
    m_fShow =  m_pData->pDetails->pInstallInfo->dwActFlags & ACTFLG_UserInstall ? 1 : 0;
    CPropertyPage::OnInitDialog();

    // unmarshal the IAppManagerActions interface
    HRESULT hr = CoGetInterfaceAndReleaseStream(m_pIStreamAM, IID_IAppManagerActions, (void **) &m_pIAppManagerActions);
    if (!SUCCEEDED(hr))
    {
#if DBG == 1
        ::MessageBox(NULL,
                     L"Couldn't marshal IAppManagerActions",
                     L"DEBUG ERROR",
                     MB_OK);
#endif
        m_pIAppManagerActions = NULL;
        return FALSE;
        // BUGBUG - what should I do here?  Disallow changes?
    }

    // unmarshal the IClassAdmin interface
    hr = CoGetInterfaceAndReleaseStream(m_pIStream, IID_IClassAdmin, (void **) &m_pIClassAdmin);
    if (!SUCCEEDED(hr))
    {
#if DBG == 1
        ::MessageBox(NULL,
                     L"Couldn't marshal IClassAdmin",
                     L"DEBUG ERROR",
                     MB_OK);
#endif
        m_pIClassAdmin = NULL;
        // BUGBUG - what should I do here?  Disallow changes?
    }

    ::LoadString(ghInstance, IDS_ASSIGNED, szBuffer, 256);
    m_szAssigned = szBuffer;
    // Test to be sure it can be assigned.
    // If it's not a Darwin package then it can't be assigned and
    // the option won't even be presented to the user.

    if (m_pIAppManagerActions)
    {
        hr = m_pIAppManagerActions->CanPackageBeAssigned(m_cookie);
    }
    if (hr == ERROR_SUCCESS)
    {
        m_cbDeploy.AddString(szBuffer);
    }
    ::LoadString(ghInstance, IDS_PUBLISHED, szBuffer, 256);
    m_szPublished = szBuffer;
    m_cbDeploy.AddString(szBuffer);
    m_cbDeploy.SelectString(0, m_szDeploy);
#if 0
    int i;
    for (i = 0; i < (sizeof(m_rgszOS) / sizeof(m_rgszOS[0])); i++)
    {
        ::LoadString(ghInstance, IDS_OS + i + 1, szBuffer, 256);
        m_rgszOS[i] = szBuffer;
        m_cbOS.AddString(szBuffer);
    }
    m_cbOS.SetCurSel(m_pData->pDetails->Platform.dwPlatformId);

    for (i = 0; i < (sizeof(m_rgszCPU) / sizeof(m_rgszCPU[0])); i++)
    {
        ::LoadString(ghInstance, IDS_HW + (i == 0 ? PROCESSOR_ARCHITECTURE_INTEL : PROCESSOR_ARCHITECTURE_ALPHA), szBuffer, 256);
        m_rgszCPU[i] = szBuffer;
        m_cbCPU.AddString(szBuffer);
    }
    m_cbCPU.SetCurSel(m_pData->pDetails->Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA ? 1 : 0);
#endif
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}

void CGeneralPage::OnChangeShow()
{
    // TODO: If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CPropertyPage::OnInitDialog()
    // function to send the EM_SETEVENTMASK message to the control
    // with the ENM_CHANGE flag ORed into the lParam mask.

    // TODO: Add your control notification handler code here

    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangePath()
{
    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangeCPU()
{
    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangeOS()
{
    TCHAR * rgszVer[] =
    {
        _T("3.1"),
        _T("4.1"),
        _T("5.0")
    };
    int i = m_cbOS.GetCurSel();
    m_szVer = rgszVer[i];
    GetDlgItem(IDC_VERSION)->SetWindowText(m_szVer);
    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangeVersion()
{
    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangeName()
{
    // TODO: If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CPropertyPage::OnInitDialog()
    // function to send the EM_SETEVENTMASK message to the control
    // with the ENM_CHANGE flag ORed into the lParam mask.

    // TODO: Add your control notification handler code here

    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnChangeDescription()
{
    // TODO: If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CPropertyPage::OnInitDialog()
    // function to send the EM_SETEVENTMASK message to the control
    // with the ENM_CHANGE flag ORed into the lParam mask.

    // TODO: Add your control notification handler code here
    SetModified();
    m_bUpdate = TRUE;
}

void CGeneralPage::OnSelchangeDeploy()
{
    // TODO: Add your control notification handler code here
    SetModified();
    m_bUpdate = TRUE;
}