// XmlSchedule.cpp: implementation of the CXmlSchedule class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Schedule.h"
#include "FileFind.h"
#include "GPRMCData.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

extern CConfig  g_Config;
extern BOOL    g_bExitDownloadThread;
extern BOOL    IsFreeDiskSpaceEnough(DWORDLONG rdwDiskSpace);
extern CString  GetMacAddress(void);
extern CString  GetCurrentDirectory();
extern CString  GetSoftwareVersion(CString filePath);

CScheduler::CScheduler(HWND hParent)
{
  MYTRACE(L"*** Scheduler Initiated.");
  m_hParent=hParent;
  
  //Init all variables
  m_DownloadPath    = g_Config.m_Content.m_DownloadPath;
  m_UserName      = g_Config.m_Content.m_UserName;
  m_Password      = g_Config.m_Content.m_Password;
  m_MacAddress    = GetMacAddress();
  m_ScheduleXmlId    = L"";
  
  m_DownloadTempPath.Format(L"%sTemp\\",m_DownloadPath);
  m_VideosDownloadPath.Format(L"%sVideos\\",m_DownloadPath);
  m_PicturesDownloadPath.Format(L"%sPictures\\",m_DownloadPath);
  
  //Create Paths
  CreateDirectory(m_DownloadPath,NULL);
  CreateDirectory(m_VideosDownloadPath,NULL);
  CreateDirectory(m_PicturesDownloadPath,NULL);
  CreateDirectory(m_DownloadTempPath,NULL);
  
  //Load current schedule xml
    this->LoadSchedule(m_DownloadPath);

  //Only allow delete of contents when # of minimum contents exist in XML file
  if (this->m_SchedulerProfile.GetContentSize() > 0)
  {
    //Delete all contents not on schedule list
    this->DeleteContents(m_VideosDownloadPath);
    this->DeleteContents(m_PicturesDownloadPath);
  }
  m_hRunCompleted=CreateEvent(NULL,FALSE,TRUE,L"Run Completed Event");
}

BOOL CScheduler::Run()
{
  CTaskList::Abort(FALSE);

  if(!IsFreeDiskSpaceEnough(1024*1024*10))
    return TRUE;

  ResetEvent(m_hRunCompleted);
  MYTRACE(L"*** Begin Download ***");

  //Download new schedule xml file
  if(!g_bExitDownloadThread)
    DownloadScheduleFile();

  //Download videos and pictures
  if(!g_bExitDownloadThread)
    DownloadCurrentTask();      

  MYTRACE(L"*** End Download ***");
  SetEvent(m_hRunCompleted);
  
  return TRUE;
}

BOOL CScheduler::DownloadScheduleFile()
{
  CString requestUrl=L"";
  CString tempFileName=XML_SCHEDULE;
  CString appPath=GetCurrentDirectory()+APP_FILE_NAME;
  CString tempSchedulePath=m_DownloadTempPath+tempFileName;
  CString csPlaylistPattern=this->GetPlayablePattern();
  CString sProdVersion=GetSoftwareVersion(appPath);

  // construct the URL request
  requestUrl.Format(L"%s?Action=GET_SCH&DevID=%s&AppID=%s&XmlID=%s&Gprmc=%s&CntStatus=%s", 
    g_Config.m_Content.m_ScheduleUrl, this->m_MacAddress, sProdVersion, m_ScheduleXmlId, 
    CGPRMCData::c_GprmcData,csPlaylistPattern);

  CTaskList dlSchTask;
  CTaskItem item;
  item.m_Url=requestUrl;
  item.m_FileName  = tempFileName;
  item.m_FilePath = tempSchedulePath;
  item.m_UserName = m_UserName;
  item.m_Password = m_Password;

  BOOL bDownloadScheduleSuccess=FALSE;
  MYTRACE(L"Requesting Schedule File: %s", item.m_Url);

  for (int i = 0; i < 25; i++)
  {
    DeleteFile(item.m_FilePath);
    bDownloadScheduleSuccess = dlSchTask.StartDownload(&item);

    // retry download schedule file on fails
    if (bDownloadScheduleSuccess)
    {
      MYTRACE(L"Download Schedule File: Ok.");
      LOGDATA(LOG_TYPE_3G__, L"SUCC");
      
      if (this->LoadSchedule(m_DownloadTempPath))
      {
        CopyFile(tempSchedulePath, g_Config.m_Content.m_DownloadPath+XML_SCHEDULE, FALSE);
      }
      break;
    }
    MYTRACE(L"Retrying download Schedule File.");
    LOGDATA(LOG_TYPE_3G__, L"FAIL");
    
    // within the 30sec, each sec check if customer is on, if so, exit all download and play videos
    for (int j = 0; j < 30; j++)
    {      
      if (g_bExitDownloadThread)
        return FALSE;

      Sleep(1000);
    }
  }
  return TRUE;
}

BOOL CScheduler::DownloadCurrentTask()
{
  CString szDownloadPath=L"";
  CTaskList* taskList=new CTaskList();
    int nCount = this->m_SchedulerProfile.GetContentSize();

    for (int i = 0; i < nCount; i++)
    {
        CContentListProfile* pp = this->m_SchedulerProfile.GetContentAt(i);    
        int nCont = pp->GetSize();
    
        for (int j = 0; j < nCont; j++)
        {
            CContentDetailProfile* pdp = pp->GetAt(j);
      RESOURCETYPE type;

      if (pdp->m_FileType.Compare(TYPE_BIN) == 0)
        type=BINTYPE, szDownloadPath=m_VideosDownloadPath;
      else if (pdp->m_FileType.Compare(TYPE_VIDEO) == 0)
        type=VIDEOTYPE, szDownloadPath=m_VideosDownloadPath;
      else if (pdp->m_FileType.Compare(TYPE_PICTURE) == 0)
        type=PICTURETYPE, szDownloadPath=m_PicturesDownloadPath;
      else
        szDownloadPath=m_DownloadTempPath;

      if (NeedToDownloadFile(szDownloadPath+pdp->m_FileName, _ttol(pdp->m_FileSize)))
      {
        CTaskItem *item=taskList->AddItem();
        
        item->m_ResourceType=type;
        item->m_Url=pdp->m_Url;
        item->m_FileName=pdp->m_FileName;
        item->m_FilePath=szDownloadPath+item->m_FileName;
        item->m_UserName=m_UserName;
        item->m_Password=m_Password;
      }
      else
      {
        #ifdef QA_RELEASE
        MYTRACE(L"Completed Download File [%s] 100%%", szDownloadPath+pdp->m_FileName);
        #endif
      }
        }
    }

  // start download all items
  if(taskList->Run(m_hParent) > 0)
  {
    delete taskList;
    taskList=NULL;    
  }

  // reload play list every time
  MYTRACE(L"Reloading Playlist");
  ::PostMessage(m_hParent,WM_PLAYLIST_CHANGED,0,0);
  return TRUE;
}

BOOL CScheduler::DownloadFile(const CString& szUrl, const CString& sFileName)
{
    /*
    CTaskList task;
    CTaskItem item;
    item.m_Url = szUrl;
    item.m_FileName=sFileName;
    item.m_FilePath=glob_CurrentPath+glob_Config.m_Content.m_DownloadPath+item.m_FileName;
    item.m_UserName=glob_Config.m_Content.m_UserName;
    item.m_Password=glob_Config.m_Content.m_Password;

    DeleteFile(item.m_FilePath);

    if(task.StartDownload(&item))  
        return TRUE;    

    return FALSE;
    */
    return TRUE;
}

BOOL CScheduler::NeedToDownloadFile(const CString& szFilePath, const DWORD dwFileSize)
{
  return !this->IsEqualFileSize(szFilePath, dwFileSize);
}

BOOL CScheduler::LoadSchedule(const CString& sXmlPath)
{
    CXmlDocument xmlDoc;
    CString sFilePath=sXmlPath+XML_SCHEDULE;

  MYTRACE(L"Parsing Schedule File: %s", sFilePath);

    if (xmlDoc.Load(sFilePath))
    {
    this->m_ScheduleXmlId = this->GetHeaderAttribute(xmlDoc, L"@xmlid");    

        this->ParseVideoList(xmlDoc);
        this->ParsePictureList(xmlDoc);
        this->ParseContentList(xmlDoc);
    this->ParseZoneList(xmlDoc);

    MYTRACE(L"Parsing Schedule File: Ok.");
    }
  else
  {
    MYTRACE(L"Unable to load Schedule File.");
    return FALSE;
  }
  return TRUE;
}

CString CScheduler::GetHeaderAttribute(CXmlDocument& xmlDoc, const CString& csAttr)                  
{
    CXmlNodeList xmlList;
  
    if (xmlDoc.SelectNodes(L"schedule", &xmlList))
    {    
        CXmlNode xmlNode;
    
        if (xmlList.GetAt(0, &xmlNode))
    {
      return xmlNode.GetAttribute(csAttr);
    }    
    }
    return L"";
}

BOOL CScheduler::ParseVideoList(CXmlDocument& xmlDoc)
{
    CXmlNodeList xmlList;

    if (xmlDoc.SelectNodes(L"schedule/videolists/videolist", &xmlList))
    {
        this->m_SchedulerProfile.m_VideoListProfile.RemoveAll();

        for (int i = 0; i < xmlList.GetSize(); i++)
        {
            CXmlNode xmlNode;
            CXmlNodeList xmlDList;

            if (!xmlList.GetAt(i, &xmlNode))
                continue;

            CVideoListProfile* plist = this->m_SchedulerProfile.AddVideoProfile();
            plist->m_ValidDays = xmlNode.GetAttribute(L"@validdays");
            plist->m_VideoType = xmlNode.GetAttribute(L"@type");

            if (xmlNode.SelectNodes(L"video", &xmlDList))
            {
                for (int j = 0; j < xmlDList.GetSize(); j++)
                {
                    CXmlNode xmlDNode;

                    if (!xmlDList.GetAt(j, &xmlDNode))
                        continue;

                    CVideoContentProfile* pp= plist->AddProfile();
                    pp->m_AdvId        = xmlDNode.GetAttribute(L"@advid");
                    pp->m_ContentId      = xmlDNode.GetAttribute(L"@contentid");
                    pp->m_RightPicListId  = xmlDNode.GetAttribute(L"@rightpiclistid");
                    pp->m_BottomPicListId  = xmlDNode.GetAttribute(L"@bottompiclistid");
                    pp->m_Layout      = xmlDNode.GetAttribute(L"@layout");
          pp->m_StartTime      = xmlDNode.GetAttribute(L"@starttime");
          pp->m_EndTime      = xmlDNode.GetAttribute(L"@endtime");
          pp->m_CommenceDate    = xmlDNode.GetAttribute(L"@commencedate");
          pp->m_ExpireDate    = xmlDNode.GetAttribute(L"@expiredate");
          pp->m_ZoneId      = xmlDNode.GetAttribute(L"@zoneid");
          pp->m_ZoneArea      = xmlDNode.GetAttribute(L"@zonearea");
          pp->m_AudioLevel    = xmlDNode.GetAttribute(L"@audiolevel");
          pp->m_BrightnessLevel  = xmlDNode.GetAttribute(L"@brightnesslevel");
                }
            }
        }
        return TRUE;
    }
    return FALSE;
}

BOOL CScheduler::ParsePictureList(CXmlDocument& xmlDoc)
{
    CXmlNodeList xmlList;

    if (xmlDoc.SelectNodes(L"schedule/picturelists/picturelist", &xmlList))
    {
        this->m_SchedulerProfile.m_PictureListProfile.RemoveAll();

        for (int i = 0; i < xmlList.GetSize(); i++)
        {
            CXmlNode xmlNode;
            CXmlNodeList xmlDList;

            if (!xmlList.GetAt(i, &xmlNode))
                continue;

            CPictureListProfile* plist = this->m_SchedulerProfile.AddPictureProfile();
            plist->m_PictureId = xmlNode.GetAttribute(L"@id");
            plist->m_Duration = xmlNode.GetAttribute(L"@duration");

            if (xmlNode.SelectNodes(L"picture", &xmlDList))
            {
                for (int j = 0; j < xmlDList.GetSize(); j++)
                {
                    CXmlNode xmlDNode;

                    if (!xmlDList.GetAt(j, &xmlDNode))
                        continue;

                    CPictureDetailProfile* pp = plist->AddProfile();
                    pp->m_PictureId      = xmlDNode.GetAttribute(L"@picid");
                    pp->m_FlyDirection   = xmlDNode.GetAttribute(L"@flydirection");
                }
            }
        }
        return TRUE;
    }
    return FALSE;
}

BOOL CScheduler::ParseContentList(CXmlDocument& xmlDoc)
{
    CXmlNodeList xmlList;

    if (xmlDoc.SelectNodes(L"schedule/contentlists/contentlist", &xmlList))
    {
        this->m_SchedulerProfile.m_ContentListProfile.RemoveAll();

        for (int i = 0; i < xmlList.GetSize(); i++)
        {
            CXmlNode xmlNode;
            CXmlNodeList xmlDList;

            if (!xmlList.GetAt(i, &xmlNode))
                continue;

            CContentListProfile* plist = this->m_SchedulerProfile.AddContentProfile();
            plist->m_ContentId = xmlNode.GetAttribute(L"@id");

            if (xmlNode.SelectNodes(L"content", &xmlDList))
            {
                for (int j = 0; j < xmlDList.GetSize(); j++)
                {
                    CXmlNode xmlDNode;

                    if (!xmlDList.GetAt(j, &xmlDNode))
                        continue;

                    CContentDetailProfile* pp = plist->AddProfile();
                    pp->m_Url       = xmlDNode.GetAttribute(L"@url");
                    pp->m_FileName  = xmlDNode.GetAttribute(L"@file");
                    pp->m_FileType  = xmlDNode.GetAttribute(L"@type");
                    pp->m_FileSize  = xmlDNode.GetAttribute(L"@size");
                }
            }
        }
        return TRUE;
    }
    return FALSE;
}

BOOL CScheduler::ParseZoneList(CXmlDocument& xmlDoc)
{
    CXmlNodeList xmlList;
  
    if (xmlDoc.SelectNodes(L"schedule/zonelists/zone", &xmlList))
    {
        this->m_SchedulerProfile.m_ZoneListProfile.RemoveAll();
    
        for (int i = 0; i < xmlList.GetSize(); i++)
        {
            CXmlNode xmlNode;
            CXmlNodeList xmlDList;
      
            if (!xmlList.GetAt(i, &xmlNode))
                continue;
      
            CZoneListProfile* plist = this->m_SchedulerProfile.AddZoneProfile();
            plist->m_Name   = xmlNode.GetAttribute(L"@name");
            plist->m_ZoneId = xmlNode.GetAttribute(L"@id");
            plist->m_Lat    = xmlNode.GetAttribute(L"@lat");
            plist->m_Lon    = xmlNode.GetAttribute(L"@lon");
            plist->m_Radius = xmlNode.GetAttribute(L"@radius");
        }
        return TRUE;
    }
    return FALSE;
}

CVideoListProfile* CScheduler::GetPlayList(const CString& csTypeId)
{
    int nCount = this->m_SchedulerProfile.GetVideoSize();

    for (int i = 0; i < nCount; i++)
    {
        CVideoListProfile* pp = this->m_SchedulerProfile.GetVideoAt(i);

        if (pp->m_VideoType.Compare(csTypeId) == 0)
            return pp;
    }
    return NULL;
}

CPictureListProfile* CScheduler::GetPictureList(const CString& csTypeId)
{
    int nCount = this->m_SchedulerProfile.GetPictureSize();

    for (int i = 0; i < nCount; i++)
    {
        CPictureListProfile* pp = this->m_SchedulerProfile.GetPictureAt(i);

        if (pp->m_PictureId.Compare(csTypeId) == 0)
            return pp;
    }
    return NULL;
}

CContentListProfile* CScheduler::GetContentList(const CString& csTypeId)
{
    int nCount = this->m_SchedulerProfile.GetContentSize();

    for (int i = 0; i < nCount; i++)
    {
        CContentListProfile* pp = this->m_SchedulerProfile.GetContentAt(i);

        if (pp->m_ContentId.Compare(csTypeId) == 0)
            return pp;
    }
    return NULL;
}

CZoneListProfile* CScheduler::GetZoneList(const CString& csTypeId)
{
    int nCount = this->m_SchedulerProfile.GetZoneSize();
  
    for (int i = 0; i < nCount; i++)
    {
        CZoneListProfile* pp = this->m_SchedulerProfile.GetZoneAt(i);
    
        if (pp->m_ZoneId.Compare(csTypeId) == 0)
            return pp;
    }
    return NULL;
}

BOOL CScheduler::LoadPlayList()
{
  m_PlayList.RemoveAll();

  CVideoList* item;
  
  // customer playlist
  item=&m_PlayList.m_SpecialVideoList;
  item->Reset();
  item->m_GUID=L"";
  item->m_ValidDays=L"1,2,3,4,5,6,7";
  item->m_StartTimes=L"";
  item->m_ListType=(ListType)3;
  item->Init();  
  this->LoadVideoList(item, PLAYLIST_CUSTOMER);

  // normal playlist
  item=&m_PlayList.m_NormalVideoList;
  item->Reset();
  item->m_GUID=L"";
  item->m_ValidDays=L"1,2,3,4,5,6,7";
  item->m_StartTimes=L"";
  item->m_ListType=(ListType)1;
  item->Init();  
  this->LoadVideoList(item, PLAYLIST_NORMAL);

  // trigger playlist
  item=&m_PlayList.m_TriggerVideoList;
  item->Reset();
  item->m_GUID=L"";
  item->m_ValidDays=L"1,2,3,4,5,6,7";
  item->m_StartTimes=L"";
  item->m_ListType=(ListType)4;
  item->Init();  
  this->LoadVideoList(item, PLAYLIST_TRIGGER);

  // news playlist
  item=&m_PlayList.m_TriggerAdVideoList;
  item->Reset();
  item->m_GUID=L"";
  item->m_ValidDays=L"1,2,3,4,5,6,7";
  item->m_StartTimes=L"";
  item->m_ListType=(ListType)5;
  item->Init();  
  this->LoadVideoList(item, PLAYLIST_NEWS);

  return TRUE;
}

void CScheduler::LoadVideoList(CVideoList* videoList, const CString& szPlayType)
{
    CVideoListProfile* vid = this->GetPlayList(szPlayType);

  if (vid == NULL)
    return;

    int nVidCount = vid->GetSize();
  
    for (int iVid = 0; iVid < nVidCount; iVid++)
    {
        CVideoContentProfile* con = vid->GetAt(iVid);  
        CContentListProfile* clp = this->GetContentList(con->m_ContentId);
        CContentDetailProfile* cdp = clp->GetAt(0);

    CVideoItem *item=videoList->AddItem(cdp->m_FileName);
    item->m_AdvId=con->m_AdvId.IsEmpty() ? con->m_ContentId : con->m_AdvId;
    item->m_ContentId=con->m_ContentId;
    item->m_FilePath=m_VideosDownloadPath+item->m_GUID;
    item->m_StartTime=con->m_StartTime;
    item->m_EndTime=con->m_EndTime;    
    item->m_CommenceDate=con->m_CommenceDate;
    item->m_ExpireDate=con->m_ExpireDate;
    item->m_ZoneId=con->m_ZoneId;
    item->m_AudioLevel=con->m_AudioLevel;
    item->m_BrightnessLevel=con->m_BrightnessLevel;
    item->m_Status=this->IsEqualFileSize(item->m_FilePath, _ttol(cdp->m_FileSize));
    item->m_ZonePlay=con->m_ZoneArea.Compare(L"deny") == 0 ? FALSE : TRUE;

    if (cdp->m_FileType.Compare(TYPE_BIN) == 0)
      item->m_ResourceType=BINTYPE;
    else if (cdp->m_FileType.Compare(TYPE_VIDEO) == 0)
      item->m_ResourceType=VIDEOTYPE;
    else if (cdp->m_FileType.Compare(TYPE_PICTURE) == 0)
      item->m_ResourceType=PICTURETYPE;

    if (item->m_Status)
    {
      CString layout=con->m_Layout;
      
      if(layout=="")
        item->m_Layout=LAYOUT_FULLSCREEN;
      else
        item->m_Layout=(Layout)_ttoi(layout);
      
      CString rightPictureListID=con->m_RightPicListId;
      CString bottomPictureListID=con->m_BottomPicListId;
      
      if(rightPictureListID!="")
      {
        item->m_RightPictureList=new CPictureList(rightPictureListID);
        LoadRefPictureList(item->m_RightPictureList);
        //item->m_RightPictureList->Reset();      
      }
      
      if(bottomPictureListID!="")
      {
        item->m_BottomPictureList=new CPictureList(bottomPictureListID);
        LoadRefPictureList(item->m_BottomPictureList);
        //item->m_BottomPictureList->Reset();      
      }
    }
    }
}

void CScheduler::LoadRefPictureList(CPictureList *pictureList)
{
  CPictureListProfile* pic = this->GetPictureList(pictureList->m_GUID);

  if (pic == NULL)
    return;

    int nPicCount = pic->GetSize();
  
  CString duration=pic->m_Duration;
  if(duration=="")
  {
    pictureList->m_Duration=10;
  }
  else
  {
    pictureList->m_Duration=_ttoi(duration);
    pictureList->m_Duration=pictureList->m_Duration < 1 ? 1 : pictureList->m_Duration;
  }

    for (int iPic = 0; iPic < nPicCount; iPic++)
    {
    CPictureDetailProfile *pd  = pic->GetAt(iPic);
    CPictureItem * item=pictureList->AddItem(pd->m_PictureId);
    item->m_FilePath=m_PicturesDownloadPath+item->m_GUID;
    item->m_Status=this->IsEqualFileSize(item->m_FilePath, this->GetFileSizeInScheduleXml(item->m_GUID));
    item->m_SizeMode=1;
    
    //Get fly direction
    CString direction=pd->m_FlyDirection;
    if(direction=="")
    {
      item->m_FlyDirection=FlyDirection_FromLeft;
    }
    else
    {
      item->m_FlyDirection=(FlyDirection)_ttoi(direction);
    }
  }
}

BOOL CScheduler::IsEqualFileSize(const CString& szFilePath, const DWORD dwFileSize)
{
  BOOL bRet=FALSE;
  HANDLE hFile = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  

  if (hFile != INVALID_HANDLE_VALUE)
  {
    if (GetFileSize(hFile, NULL)==dwFileSize)
      bRet=TRUE;

    CloseHandle(hFile);
  }
  return bRet;
}

BOOL CScheduler::IsFileExistInScheduleXml(const CString& szFileName)
{
    int nCount = this->m_SchedulerProfile.GetContentSize();
  
    for (int i = 0; i < nCount; i++)
    {
        CContentListProfile* pp = this->m_SchedulerProfile.GetContentAt(i);
        int nFiles = pp->GetSize();
    
        for (int f = 0; f < nFiles; f++)
        {
            CContentDetailProfile *cd = pp->GetAt(f);
      
            if (cd->m_FileName.CompareNoCase(szFileName) == 0)
                return TRUE;
        }
    }
    return FALSE;
}

LONG CScheduler::GetFileSizeInScheduleXml(const CString& szFileName)
{
    int nCount = this->m_SchedulerProfile.GetContentSize();
  
    for (int i = 0; i < nCount; i++)
    {
        CContentListProfile* pp = this->m_SchedulerProfile.GetContentAt(i);
        int nFiles = pp->GetSize();
    
        for (int f = 0; f < nFiles; f++)
        {
            CContentDetailProfile *cd = pp->GetAt(f);
      
            if (cd->m_FileName.CompareNoCase(szFileName) == 0)
                return _ttol(cd->m_FileSize);
        }
    }
    return 0;
}

BOOL CScheduler::DeleteContents(const CString& szFilePath)
{
  CString sFileName = L"";
  CString sFilePath = L"";
  WIN32_FIND_DATA lpFindFileData;
  
  HANDLE hFind = FindFirstFile(szFilePath + L"*.*", &lpFindFileData);
  
  if (hFind == INVALID_HANDLE_VALUE)
    return FALSE;
  
  do
  {
    sFileName = lpFindFileData.cFileName;
    sFilePath = szFilePath + sFileName;
    
    if (sFileName == "." || sFileName == "..")
      continue;
    
    if (!(lpFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    {  
      if (!this->IsFileExistInScheduleXml(sFileName))
      {
        MYTRACE(L"Deleted File: %s", sFilePath);
        DeleteFile(sFilePath);
      }
    }
  }
  while (FindNextFile(hFind, &lpFindFileData));
  CloseHandle(hFind);

  return TRUE;
}

CString CScheduler::GetPlayablePattern()
{
  CString szPlayPattern=L"";
  CString szDownloadPath=L"";

  if (this->LoadSchedule(m_DownloadPath))
  {
    int nCount = this->m_SchedulerProfile.GetContentSize();
    
    for (int i = 0; i < nCount; i++)
    {
      CContentListProfile* pp = this->m_SchedulerProfile.GetContentAt(i);    
      int nCont = pp->GetSize();
      
      for (int j = 0; j < nCont; j++)
      {
        CContentDetailProfile* pdp = pp->GetAt(j);
        RESOURCETYPE type;
        
        if (pdp->m_FileType.Compare(TYPE_BIN) == 0)
          type=BINTYPE, szDownloadPath=m_VideosDownloadPath;
        else if (pdp->m_FileType.Compare(TYPE_VIDEO) == 0)
          type=VIDEOTYPE, szDownloadPath=m_VideosDownloadPath;
        else if (pdp->m_FileType.Compare(TYPE_PICTURE) == 0)
          type=PICTURETYPE, szDownloadPath=m_PicturesDownloadPath;
        else
          szDownloadPath=m_DownloadTempPath;
        
        if (this->IsEqualFileSize(szDownloadPath+pdp->m_FileName, _ttol(pdp->m_FileSize)))
          szPlayPattern.Insert(szPlayPattern.GetLength(), L"1");
        else
          szPlayPattern.Insert(szPlayPattern.GetLength(), L"0");
      }
    }
  }
  return szPlayPattern;
}