private void HandleLocalFilesInDir(string aDirectory, ref List<GUIListItem> aItemsList, bool aHasRedbookDetails,
                                       bool useCache, bool loadHidden)
    {
      //This function is only used inside GetDirectoryUnProtectedExt. GetDirectoryUnProtectedExt is 
      //mainly used for internal loading. That means it isn't called when the user explicitly enters a 
      //directory, but just when MP means it needs to query a directory. The bad thing is that the code 
      //has grown much over the time and these function is called way too often, which can result in very bad performance
      //Anyway it isn't really a good idea to always reload a directory completely if it isn't really neccessary.
      //This change is not meant as the perfect solution, but anything other whould more or less mean a complete remake.
      //The main purpose of this tweak is to boost the performance when starting/stopping playback, because atm
      //start playback triggers a complete reload 2-3 times and stop playback another 1-2 times.

      if (useCache && !string.IsNullOrEmpty(_cachedDir) && aDirectory == _cachedDir)
      {
        aItemsList.AddRange(_cachedItems);
        return;
      }

      _cachedItems.Clear();
      _cachedDir = null;

      try
      {
        Win32API.WIN32_FIND_DATA fd = new Win32API.WIN32_FIND_DATA();
        fd.cFileName = new String(' ', 256);
        fd.cAlternate = new String(' ', 14);
        // http://msdn.microsoft.com/en-us/library/aa364418%28VS.85%29.aspx
        IntPtr handle = Win32API.FindFirstFile(aDirectory + @"\*.*", out fd);

        int count = 0;
        do
        {
          try
          {
            count++;

            if (fd.cFileName == "." || fd.cFileName == "..")
            {
              continue;
            }

            GUIListItem item;
            string FileName = aDirectory + @"\" + fd.cFileName;

            long ftCreationTime = (((long)fd.ftCreationTime.dwHighDateTime) << 32) + fd.ftCreationTime.dwLowDateTime;
            long ftLastWriteTime = (((long)fd.ftLastWriteTime.dwHighDateTime) << 32) + fd.ftLastWriteTime.dwLowDateTime;

            FileInformation fi = new FileInformation();

            fi.CreationTime = DateTime.FromFileTimeUtc(ftCreationTime);
            fi.ModificationTime = DateTime.FromFileTimeUtc(ftLastWriteTime);
            fi.Length = (((long)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow;

            if ((fd.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
            {
              // Skip hidden folders
              if (!loadHidden)
              {
                if ((fd.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                  continue;
              }

              string strPath = FileName.Substring(aDirectory.Length + 1);
              fi.Name = fd.cFileName;
              item = new GUIListItem(strPath, "", FileName, true, fi);

              Utils.SetDefaultIcons(item);

              string pin;
              if (!IsProtectedShare(item.Path, out pin))
              {
                Utils.SetThumbnails(ref item);
              }

              aItemsList.Add(item);
              _cachedItems.Add(item);
            }
            else
            {
              string extension = Path.GetExtension(FileName);
              if (aHasRedbookDetails)
              {
                extension = ".cda";
                FileName = string.Format("{0}\\Track{1:00}.cda", aDirectory, count);
              }

              if (IsImageFile(extension))
              {
                if (DaemonTools.IsEnabled && !IsValidExtension(FileName))
                {
                  item = new GUIListItem(Path.GetFileName(FileName), "", FileName, true, null);

                  Utils.SetDefaultIcons(item);
                  Utils.SetThumbnails(ref item);

                  aItemsList.Add(item);
                  _cachedItems.Add(item);

                  continue;
                }
              }

              if (IsValidExtension(FileName))
              {
                // Skip hidden files
                if (!loadHidden)
                {
                  if (!aHasRedbookDetails &&
                      (fd.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                    continue;
                }

                if (!aHasRedbookDetails)
                {
                  //fi = new FileInformation(FileName, false);
                  fi.Name = fd.cFileName;
                }
                else
                {
                  fi = new FileInformation();
                  fi.CreationTime = DateTime.Now;
                  fi.Length = 0;
                }

                item = new GUIListItem(Utils.GetFilename(FileName), "", FileName, false, fi);

                Utils.SetDefaultIcons(item);
                Utils.SetThumbnails(ref item);

                aItemsList.Add(item);
                _cachedItems.Add(item);
              }
            }
          }
          catch (Exception exi)
          {
            Log.Error("VirtualDirectory: Could not fetch folder contents for {0}: {1}", aDirectory, exi.Message);
          }
        } while (Win32API.FindNextFile(handle, ref fd) != 0);

        Win32API.FindClose(handle);

        _cachedDir = aDirectory;
      }
      catch (Exception ex)
      {
        Log.Error("VirtualDirectory: Could not browse folder {0}: {1}", aDirectory, ex.Message);

        _cachedItems.Clear();
        _cachedDir = null;
      }
    }
Example #2
0
    public static void PlayMovie(int idMovie, bool requestPin)
    {

      int selectedFileIndex = 1;

      if (IsStacked)
      {
        selectedFileIndex = 0;
      }

      ArrayList movieFiles = new ArrayList();
      VideoDatabase.GetFilesForMovie(idMovie, ref movieFiles);

      if (movieFiles.Count <= 0 || !CheckMovie(idMovie))
      {
        return;
      }

      bool askForResumeMovie = true;
      int movieDuration = 0;

      List<GUIListItem> items = new List<GUIListItem>();

      foreach (string file in movieFiles)
      {
        FileInformation fi = new FileInformation();
        GUIListItem item = new GUIListItem(Util.Utils.GetFilename(file), "", file, false, fi);
        items.Add(item);

        if (!WakeUpSrv(item.Path))
        {
          return;
        }
      }

      if (items.Count <= 0)
      {
        return;
      }

      if (requestPin)
      {
        string strDir = Path.GetDirectoryName(items[0].Path);

        if (strDir != null && strDir.EndsWith(@"\"))
        {
          strDir = strDir.Substring(0, strDir.Length - 1);
        }

        if (strDir == null || strDir.Length > 254)
        {
          Log.Warn("GUIVideoFiles.PlayTitleMovie: Received a path which contains too many chars");
          return;
        }

        string iPincodeCorrect;
        if (_virtualDirectory.IsProtectedShare(strDir, out iPincodeCorrect))
        {
          #region Pin protected

          bool retry = true;
          {
            while (retry)
            {
              //no, then ask user to enter the pincode
              GUIMessage msgGetPassword = new GUIMessage(GUIMessage.MessageType.GUI_MSG_GET_PASSWORD, 0, 0, 0, 0, 0, 0);
              GUIWindowManager.SendMessage(msgGetPassword);

              if (msgGetPassword.Label != iPincodeCorrect)
              {
                GUIMessage msgWrongPassword = new GUIMessage(GUIMessage.MessageType.GUI_MSG_WRONG_PASSWORD, 0, 0, 0, 0, 0,
                                                             0);
                GUIWindowManager.SendMessage(msgWrongPassword);

                if (!(bool)msgWrongPassword.Object)
                {
                  return;
                }
              }
              else
              {
                retry = false;
              }
            }
          }

          #endregion
        }
      }

      //check if we can resume 1 of those movies
      if (items.Count > 1)
      {
        bool asked = false;

        for (int i = 0; i < items.Count; ++i)
        {
          GUIListItem temporaryListItem = (GUIListItem)items[i];

          if (!asked)
          {
            selectedFileIndex++;
          }

          IMDBMovie movieDetails = new IMDBMovie();
          int idFile = VideoDatabase.GetFileId(temporaryListItem.Path);

          if ((idMovie >= 0) && (idFile >= 0))
          {
            VideoDatabase.GetMovieInfo((string)movieFiles[0], ref movieDetails);
            string title = Path.GetFileName((string)movieFiles[0]);

            if ((VirtualDirectory.IsValidExtension((string)movieFiles[0], Util.Utils.VideoExtensions, false)))
            {
              Util.Utils.RemoveStackEndings(ref title);
            }

            if (movieDetails.Title != string.Empty)
            {
              title = movieDetails.Title;
            }

            int timeMovieStopped = VideoDatabase.GetMovieStopTime(idFile);

            if (timeMovieStopped > 0)
            {
              if (!asked)
              {
                asked = true;

                GUIResumeDialog.Result result =
                  GUIResumeDialog.ShowResumeDialog(title, movieDuration + timeMovieStopped,
                                                   GUIResumeDialog.MediaType.Video);

                if (result == GUIResumeDialog.Result.Abort)
                {
                  _playlistPlayer.Reset();
                  _playlistPlayer.CurrentPlaylistType = _currentPlaylistType;
                  _playlistPlayer.CurrentSong = _currentPlaylistIndex;
                  return;
                }

                if (result == GUIResumeDialog.Result.PlayFromBeginning)
                {
                  VideoDatabase.DeleteMovieStopTime(idFile);
                }
                else
                {
                  askForResumeMovie = false;
                }
              }
            }
            // Total movie duration
            movieDuration += VideoDatabase.GetVideoDuration(idFile);
          }
        }

        if (askForResumeMovie)
        {
          GUIDialogFileStacking dlg =
            (GUIDialogFileStacking)GUIWindowManager.GetWindow((int)Window.WINDOW_DIALOG_FILESTACKING);

          if (null != dlg)
          {
            dlg.SetFiles(movieFiles);
            dlg.DoModal(GUIWindowManager.ActiveWindow);
            selectedFileIndex = dlg.SelectedFile;
            if (selectedFileIndex < 1)
            {
              return;
            }
          }
        }
      }

      // Get current playlist
      _currentPlaylistType = new PlayListType();
      _currentPlaylistType = _playlistPlayer.CurrentPlaylistType;
      _currentPlaylistIndex = _playlistPlayer.CurrentSong;
      
      _playlistPlayer.Reset();
      _playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_VIDEO_TEMP;
      PlayList playlist = _playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_VIDEO_TEMP);
      playlist.Clear();

      for (int i = selectedFileIndex - 1; i < movieFiles.Count; ++i)
      {
        string movieFileName = (string)movieFiles[i];
        PlayListItem newitem = new PlayListItem();
        newitem.FileName = movieFileName;
        newitem.Type = PlayListItem.PlayListItemType.Video;
        playlist.Add(newitem);
      }

      // play movie...
      PlayMovieFromPlayList(askForResumeMovie, requestPin);
    }
Example #3
0
    protected override void OnClick(int iItem)
    {
      GUIListItem item = facadeLayout.SelectedListItem;
      TotalMovieDuration = 0;
      IsStacked = false;
      StackedMovieFiles.Clear();

      if (item == null)
      {
        _playClicked = false;
        return;
      }
      
      if (!WakeUpSrv(item.Path))
      {
        return;
      }

      string path = item.Path;

      if (item.IsBdDvdFolder)
      {
        // Check if folder is actually a DVD. If so don't browse this folder, but play the DVD!
        if (File.Exists(path + @"\VIDEO_TS\VIDEO_TS.IFO"))
        {
          path = item.Path + @"\VIDEO_TS\VIDEO_TS.IFO";
        }
        // Then it's a Blu-Ray. Play the Blu-Ray!
        else
        {
          path = item.Path + @"\BDMV\index.bdmv";
        }
      }

      if ((item.IsFolder && !item.IsBdDvdFolder))
      {
        // Play all in folder
        if (_playClicked)
        {
          if (!item.IsRemote && item.Label != ".." && !VirtualDirectory.IsImageFile(Path.GetExtension(item.Path)))
          {
            if (!_virtualDirectory.RequestPin(item.Path))
            {
              _playClicked = false;
              return;
            }

            OnPlayAll(item.Path);
            _playClicked = false;
          }
        }
        else
        {
          _currentSelectedItem = -1;

          if (facadeLayout != null)
          {
            _history.Set(facadeLayout.SelectedListItemIndex.ToString(), _currentFolder);
          }

          LoadDirectory(path, true);
        }
      }
      else
      {
        if (!_virtualDirectory.RequestPin(path))
        {
          _playClicked = false;
          return;
        }
        
        if (_virtualDirectory.IsRemote(path))
        {
          if (!_virtualDirectory.IsRemoteFileDownloaded(path, item.FileInfo.Length))
          {
            if (!_virtualDirectory.ShouldWeDownloadFile(path))
            {
              _playClicked = false;
              return;
            }
            
            if (!_virtualDirectory.DownloadRemoteFile(path, item.FileInfo.Length))
            {
              //show message that we are unable to download the file
              GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SHOW_WARNING, 0, 0, 0, 0, 0, 0);
              msg.Param1 = 916;
              msg.Param2 = 920;
              msg.Param3 = 0;
              msg.Param4 = 0;
              GUIWindowManager.SendMessage(msg);
              _playClicked = false;
              return;
            }
            //download subtitle files
            Thread subLoaderThread = new Thread(DownloadSubtitles);
            subLoaderThread.IsBackground = true;
            subLoaderThread.Name = "SubtitleLoader";
            subLoaderThread.Start();
          }
        }

        if (item.FileInfo != null)
        {
          if (!_virtualDirectory.IsRemoteFileDownloaded(path, item.FileInfo.Length))
          {
            _playClicked = false;
            return;
          }
        }
        
        string movieFileName = path;
        movieFileName = _virtualDirectory.GetLocalFilename(movieFileName);

        if (PlayListFactory.IsPlayList(movieFileName))
        {
          LoadPlayList(movieFileName);
          _playClicked = false;
          return;
        }

        if (!CheckMovie(movieFileName))
        {
          _playClicked = false;
          return;
        }

        if (_videoInfoInShare && VideoDatabase.HasMovieInfo(movieFileName) && !_playClicked)
        {
          OnInfo(facadeLayout.SelectedListItemIndex);
          return;
        }

        bool askForResumeMovie = true;
        _playClicked = false;

        #region StackEnabled and file is stackable

        // Proceed to file stack check if file is stackable
        if (_mapSettings.Stack && IsFileStackable(movieFileName))
        {
          IsStacked = true;
          int selectedFileIndex = 0;
          int movieDuration = 0;
          ArrayList movies = new ArrayList();
          List<GUIListItem> items = new List<GUIListItem>();
          IMDBMovie movie = item.AlbumInfoTag as IMDBMovie;
          
          // This will return all stackable files for current clicked item
          // Also will add all stackable files to videodatabase if they are not exist
          StackedMovieFiles = AddFileToDatabase(movieFileName);
          
          // Add movie files to list
          foreach (string file in StackedMovieFiles)
          {
            FileInformation fi = new FileInformation();
            GUIListItem itemMovie = new GUIListItem(Util.Utils.GetFilename(file), "", file, false, fi);
            items.Add(itemMovie);
          }
          
          // In the list must be at least 2 files so we check stackable movie for resume 
          // (which file have a stop time)
          bool asked = false;
          string title = item.Label; // Dlg title

          if (movie != null && !movie.IsEmpty)
          {
            title = movie.Title;
          }
          
          for (int i = 0; i < items.Count; ++i)
          {
            IMDBMovie.SetMovieData(items[i]); // This will set IMDBMovie object and it will never be null
            movie = items[i].AlbumInfoTag as IMDBMovie;
             
            if (!asked)
            {
              selectedFileIndex++;
            }

            int idFile = VideoDatabase.GetFileId(movie.VideoFileName);

            if (idFile != -1)
            {
              int timeMovieStopped = VideoDatabase.GetMovieStopTime(idFile);
                
              if (timeMovieStopped > 0)
              {
                if (!asked)
                {
                  asked = true;
                  GUIResumeDialog.Result result =
                    GUIResumeDialog.ShowResumeDialog(title, movieDuration + timeMovieStopped,
                                                      GUIResumeDialog.MediaType.Video);

                  if (result == GUIResumeDialog.Result.Abort)
                  {
                    _playlistPlayer.Reset();
                    _playlistPlayer.CurrentPlaylistType = _currentPlaylistType;
                    _playlistPlayer.CurrentSong = _currentPlaylistIndex;
                    return;
                  }

                  if (result == GUIResumeDialog.Result.PlayFromBeginning)
                  {
                    VideoDatabase.DeleteMovieStopTime(idFile);
                  }
                  else
                  {
                    askForResumeMovie = false;
                  }
                }
              }
              
              // Total movie duration
              movieDuration += VideoDatabase.GetVideoDuration(idFile);
              TotalMovieDuration = movieDuration;
            }
          }

          for (int i = 0; i < items.Count; ++i)
          {
            GUIListItem temporaryListItem = (GUIListItem)items[i];
            movie = (IMDBMovie)temporaryListItem.AlbumInfoTag;

            if (Util.Utils.IsVideo(movie.VideoFileName) && !PlayListFactory.IsPlayList(movie.VideoFileName))
            {
              movies.Add(movie.VideoFileName);
            }
          }
          
          if (movies.Count == 0)
          {
            movies.Add(movieFileName);
          }

          if (movies.Count > 1)
          {
            movies.Sort();

            // Stacked movies duration
            if (TotalMovieDuration == 0)
            {
              MovieDuration(movies, false);
              StackedMovieFiles = movies;
            }

            // Ask for resume
            if (askForResumeMovie)
            {
              GUIDialogFileStacking dlg =
                (GUIDialogFileStacking) GUIWindowManager.GetWindow((int) Window.WINDOW_DIALOG_FILESTACKING);
              
              if (null != dlg)
              {
                dlg.SetFiles(movies);
                dlg.DoModal(GetID);
                selectedFileIndex = dlg.SelectedFile;
                
                if (selectedFileIndex < 1)
                {
                  return;
                }
              }
            }
          }
          // This can happen if user have one file and it is stackable (filename ends with CDx...)
          else
          {
            MovieDuration(movies, false);
          }

          // Get current playlist
          _currentPlaylistType = new PlayListType();
          _currentPlaylistType = _playlistPlayer.CurrentPlaylistType;
          _currentPlaylistIndex = _playlistPlayer.CurrentSong;
          
          _playlistPlayer.Reset();
          _playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_VIDEO_TEMP;
          PlayList playlist = _playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_VIDEO_TEMP);
          playlist.Clear();
          
          for (int i = 0; i < (int) movies.Count; ++i)
          {
            movieFileName = (string) movies[i];
            PlayListItem itemNew = new PlayListItem();
            itemNew.FileName = movieFileName;
            itemNew.Type = PlayListItem.PlayListItemType.Video;
            playlist.Add(itemNew);
          }

          // play movie...(2 or more files)
          PlayMovieFromPlayList(askForResumeMovie, selectedFileIndex - 1, true);
          return;
        }

        #endregion

        #region StackDisabled or file not stackable

        // play movie...(only 1 file)
        AddFileToDatabase(movieFileName);

        // Get current playlist
        _currentPlaylistType = new PlayListType();
        _currentPlaylistType = _playlistPlayer.CurrentPlaylistType;
        _currentPlaylistIndex = _playlistPlayer.CurrentSong;

        _playlistPlayer.Reset();
        _playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_VIDEO_TEMP;
        PlayList newPlayList = _playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_VIDEO_TEMP);
        newPlayList.Clear();
        PlayListItem NewItem = new PlayListItem();
        NewItem.FileName = movieFileName;
        NewItem.Type = PlayListItem.PlayListItemType.Video;
        newPlayList.Add(NewItem);
        PlayMovieFromPlayList(true, true);

        #endregion
      }
    }
    /// <summary>
    /// Should the file be included in the list to be added
    /// </summary>
    /// <param name="fileInfo"></param>
    private bool CheckFileForInclusion(FileInformation fileInfo)
    {
      string file = fileInfo.Name;
      bool fileinCluded = false;
      try
      {
        string ext = Path.GetExtension(file).ToLower();
        if (ext == ".m3u")
        {
          return false;
        }
        if (ext == ".pls")
        {
          return false;
        }
        if (ext == ".wpl")
        {
          return false;
        }
        if (ext == ".b4s")
        {
          return false;
        }


        // Provide an easy way to exclude problematic or unwanted files from the scan
        //if (_excludeHiddenFiles)
        //{
        //  if ((fileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
        //  {
        //    return false;
        //  }
        //}

        // Only get files with the required extension
        if (_supportedExtensions.IndexOf(ext) == -1)
        {
          return false;
        }

        // Cue Files are being processed separately
        if (CueUtil.isCueFile(file))
        {
          cueFiles.Add(file);
          return false;
        }

        // Add the files to the Hastable, which is used in the Delete Non-existing songs, to prevent file system access
        allFiles.Add(file, false);

        // Only Add files to the list, if they have been Created / Updated after the Last Import date
        if (_updateSinceLastImport && !_singleFolderScan)
        {
          if (fileInfo.CreationTime > _lastImport || fileInfo.ModificationTime > _lastImport)
          {
            _songsProcessed++;
            fileinCluded = true;
          }
          else
          {
            _songsSkipped++;
            fileinCluded = false;
          }
        }
        else
        {
          _songsProcessed++;
          fileinCluded = true;
        }
      }
      catch (UnauthorizedAccessException)
      {
        Log.Warn("Musicdatabasereorg: Not enough permissions to include file {0}", file);
      }
      catch (Exception ex)
      {
        Log.Error("Musicdatabasereorg: Cannot include file {0} because of {1}", file, ex.Message);
      }
      return fileinCluded;
    }
Example #5
0
 /// <summary>
 /// Creates a GUIListItem based on another GUIListItem.
 /// </summary>
 /// <param name="item">The item on which the new item is based.</param>
 public GUIListItem(GUIListItem item)
 {
   _label = item._label;
   _label2 = item._label2;
   _label3 = item._label3;
   _thumbNailName = item._thumbNailName;
   _smallIconName = item._smallIconName;
   _bigIconName = item._bigIconName;
   _pinIconName = item._pinIconName;
   _isSelected = item._isSelected;
   _isFolder = item._isFolder;
   _folder = item._folder;
   _dvdLabel = item._dvdLabel;
   _duration = item._duration;
   _fileInfo = item._fileInfo;
   _rating = item._rating;
   _year = item._year;
   _idItem = item._idItem;
   _tagMusic = item._tagMusic;
   _tagTv = item._tagTv;
   _tagAlbumInfo = item._tagAlbumInfo;
   _isBdDvdFolder = item._isBdDvdFolder;
 }
Example #6
0
    public GUIListItem(string aLabel, string aLabel2, string aPath, bool aIsFolder, FileInformation aFileInformation)
    {
      if (String.IsNullOrEmpty(aLabel))
      {
        return;
      }

      _label = aLabel;
      _label2 = aLabel2;
      _folder = aPath;
      _isFolder = aIsFolder;
      _fileInfo = aFileInformation;
    }
    protected override void OnClick(int iItem)
    {
      GUIListItem item = facadeLayout.SelectedListItem;
      TotalMovieDuration = 0;
      IsStacked = false;
      StackedMovieFiles.Clear();

      if (item == null)
      {
        _playClicked = false;
        return;
      }

      bool isFolderAMovie = false;
      string path = item.Path;

      if (item.IsFolder && !item.IsRemote)
      {
        // Check if folder is actually a DVD. If so don't browse this folder, but play the DVD!
        if ((File.Exists(path + @"\VIDEO_TS\VIDEO_TS.IFO")) && (item.Label != ".."))
        {
          isFolderAMovie = true;
          path = item.Path + @"\VIDEO_TS\VIDEO_TS.IFO";
        }
        // Check if folder is actually a BD. If so don't browse this folder, but play the BD!
        else if ((File.Exists(path + @"\BDMV\index.bdmv")) && (item.Label != ".."))
        {
          isFolderAMovie = true;
          path = item.Path + @"\BDMV\index.bdmv";
        }
        else
        {
          isFolderAMovie = false;
        }
      }

      if ((item.IsFolder && !isFolderAMovie))
      {
        _currentSelectedItem = -1;
        
        if (facadeLayout != null)
        {
          _history.Set(facadeLayout.SelectedListItemIndex.ToString(), _currentFolder);
        }
        
        LoadDirectory(path);
      }
      else
      {
        if (!_virtualDirectory.RequestPin(path))
        {
          _playClicked = false;
          return;
        }
        
        if (_virtualDirectory.IsRemote(path))
        {
          if (!_virtualDirectory.IsRemoteFileDownloaded(path, item.FileInfo.Length))
          {
            if (!_virtualDirectory.ShouldWeDownloadFile(path))
            {
              _playClicked = false;
              return;
            }
            
            if (!_virtualDirectory.DownloadRemoteFile(path, item.FileInfo.Length))
            {
              //show message that we are unable to download the file
              GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SHOW_WARNING, 0, 0, 0, 0, 0, 0);
              msg.Param1 = 916;
              msg.Param2 = 920;
              msg.Param3 = 0;
              msg.Param4 = 0;
              GUIWindowManager.SendMessage(msg);
              _playClicked = false;
              return;
            }
            //download subtitle files
            Thread subLoaderThread = new Thread(DownloadSubtitles);
            subLoaderThread.IsBackground = true;
            subLoaderThread.Name = "SubtitleLoader";
            subLoaderThread.Start();
          }
        }

        if (item.FileInfo != null)
        {
          if (!_virtualDirectory.IsRemoteFileDownloaded(path, item.FileInfo.Length))
          {
            _playClicked = false;
            return;
          }
        }
        
        string movieFileName = path;
        movieFileName = _virtualDirectory.GetLocalFilename(movieFileName);

        if (PlayListFactory.IsPlayList(movieFileName))
        {
          LoadPlayList(movieFileName);
          _playClicked = false;
          return;
        }

        if (!CheckMovie(movieFileName))
        {
          _playClicked = false;
          return;
        }

        if (_videoInfoInShare && VideoDatabase.HasMovieInfo(movieFileName) && !_playClicked)
        {
          OnInfo(facadeLayout.SelectedListItemIndex);
          return;
        }

        bool askForResumeMovie = true;
        _playClicked = false;
        
        // Proceed to file stack check if file is stackable
        if (_mapSettings.Stack && IsFileStackable(movieFileName))
        {
          int selectedFileIndex = 0;
          int movieDuration = 0;
          ArrayList movies = new ArrayList();

          #region Is all this really neccessary?!

          List<GUIListItem> items = new List<GUIListItem>();
          
          // If movie is not in the database (scanned) get all files
          if (!VideoDatabase.HasMovieInfo(movieFileName))
          {
            if (IsFileStackable(movieFileName))
            {
              items = _virtualDirectory.GetDirectoryUnProtectedExt(_currentFolder, true);
            }
          }
          else // Get only files related to movie from the database (movie is scanned before)
          {
            IMDBMovie movie = new IMDBMovie();
            VideoDatabase.GetMovieInfo(item.Path, ref movie);
            ArrayList movieFiles = new ArrayList();
            VideoDatabase.GetFilesForMovie(movie.ID, ref movieFiles);
            // Add movie files to list
            foreach (string file in movieFiles)
            {
              FileInformation fi = new FileInformation();
              GUIListItem itemMovie = new GUIListItem(Util.Utils.GetFilename(file), "", file, false, fi);
              items.Add(itemMovie);
            }
          }
          
          // In the list must be at least 2 files so we check stackable movie for resume 
          // (which file have a stop time)
          bool asked = false;
          ArrayList newItems = new ArrayList();
          
          for (int i = 0; i < items.Count; ++i)
          {
            GUIListItem temporaryListItem = (GUIListItem) items[i];
            
            if (Util.Utils.ShouldStack(temporaryListItem.Path, path))
            {
              IsStacked = true;
              StackedMovieFiles.Add(temporaryListItem.Path);
              
              if (!asked)
              {
                selectedFileIndex++;
              }

              IMDBMovie movieDetails = new IMDBMovie();
              int idFile = VideoDatabase.GetFileId(temporaryListItem.Path);
              int idMovie = VideoDatabase.GetMovieId(path);
              
              if ((idMovie >= 0) && (idFile >= 0))
              {
                VideoDatabase.GetMovieInfo(path, ref movieDetails);
                string title = Path.GetFileName(path);
                
                if ((VirtualDirectory.IsValidExtension(path, Util.Utils.VideoExtensions, false)))
                {
                  Util.Utils.RemoveStackEndings(ref title);
                }
                
                if (movieDetails.Title != string.Empty)
                {
                  title = movieDetails.Title;
                }

                int timeMovieStopped = VideoDatabase.GetMovieStopTime(idFile);
                
                if (timeMovieStopped > 0)
                {
                  if (!asked)
                  {
                    asked = true;

                    GUIResumeDialog.Result result =
                      GUIResumeDialog.ShowResumeDialog(title, movieDuration + timeMovieStopped,
                                                        GUIResumeDialog.MediaType.Video);

                    if (result == GUIResumeDialog.Result.Abort)
                    {
                      return;
                    }

                    if (result == GUIResumeDialog.Result.PlayFromBeginning)
                    {
                      VideoDatabase.DeleteMovieStopTime(idFile);
                      newItems.Add(temporaryListItem);
                    }
                    else
                    {
                      askForResumeMovie = false;
                      newItems.Add(temporaryListItem);
                    }
                  } //if (!asked)
                  else
                  {
                    newItems.Add(temporaryListItem);
                  }
                } //if (timeMovieStopped>0)
                else
                {
                  newItems.Add(temporaryListItem);
                }

                // Total movie duration
                movieDuration += VideoDatabase.GetVideoDuration(idFile);
                TotalMovieDuration = movieDuration;
              }
              else //if (idMovie >=0)
              {
                newItems.Add(temporaryListItem);
              }
            } //if ( MediaPortal.Util.Utils.ShouldStack(temporaryListItem.Path, path))
          }

          for (int i = 0; i < newItems.Count; ++i)
          {
            GUIListItem temporaryListItem = (GUIListItem) newItems[i];
            
            if (Util.Utils.IsVideo(temporaryListItem.Path) && !PlayListFactory.IsPlayList(temporaryListItem.Path))
            {
              if (Util.Utils.ShouldStack(temporaryListItem.Path, path))
              {
                movies.Add(temporaryListItem.Path);
              }
            }
          }
          
          if (movies.Count == 0)
          {
            movies.Add(movieFileName);
          }

          #endregion

          if (movies.Count <= 0)
          {
            return;
          }

          if (movies.Count > 1)
          {
            movies.Sort();

            for (int i = 0; i < movies.Count; ++i)
            {
              AddFileToDatabase((string) movies[i]);
            }

            // Stacked movies duration
            if (TotalMovieDuration == 0)
            {
              MovieDuration(movies, false);
              StackedMovieFiles = movies;
            }

            // Ask for rersume
            if (askForResumeMovie)
            {
              GUIDialogFileStacking dlg =
                (GUIDialogFileStacking) GUIWindowManager.GetWindow((int) Window.WINDOW_DIALOG_FILESTACKING);
              
              if (null != dlg)
              {
                dlg.SetFiles(movies);
                dlg.DoModal(GetID);
                selectedFileIndex = dlg.SelectedFile;
                
                if (selectedFileIndex < 1)
                {
                  return;
                }
              }
            }
          }
          // This can happen if user have one file and it is stackable (filename ends with CDx...)
          else if (movies.Count == 1)
          {
            AddFileToDatabase((string) movies[0]);
            MovieDuration(movies, false);
          }
          
          _playlistPlayer.Reset();
          _playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_VIDEO_TEMP;
          PlayList playlist = _playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_VIDEO_TEMP);
          playlist.Clear();
          
          for (int i = 0; i < (int) movies.Count; ++i)
          {
            movieFileName = (string) movies[i];
            PlayListItem itemNew = new PlayListItem();
            itemNew.FileName = movieFileName;
            itemNew.Type = PlayListItem.PlayListItemType.Video;
            playlist.Add(itemNew);
          }

          // play movie...(2 or more files)
          PlayMovieFromPlayList(askForResumeMovie, selectedFileIndex - 1, true);
          return;
        }

        // play movie...(only 1 file)
        AddFileToDatabase(movieFileName);

        _playlistPlayer.Reset();
        _playlistPlayer.CurrentPlaylistType = PlayListType.PLAYLIST_VIDEO_TEMP;
        PlayList newPlayList = _playlistPlayer.GetPlaylist(PlayListType.PLAYLIST_VIDEO_TEMP);
        newPlayList.Clear();
        PlayListItem NewItem = new PlayListItem();
        NewItem.FileName = movieFileName;
        NewItem.Type = PlayListItem.PlayListItemType.Video;
        newPlayList.Add(NewItem);
        PlayMovieFromPlayList(true, true);
      }
    }
    /// <summary>
    /// Gets all the filenames in a directory.
    /// Does not include subdirectories.
    /// </summary>
    /// <param name="directory">The directory to parse</param>
    /// <returns>A string array of the filenames</returns>
    public static FileInformation[] GetFileInformation(string directory, bool includeSystemAndHidden)
    {
      List<FileInformation> fi = new List<FileInformation>();
      IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
      string prefix = fileSystemPrefix;
      IntPtr findHandle = new IntPtr(0);
      WIN32_FIND_DATA findData;
      if (directory.StartsWith(@"\\"))
      {
        prefix = UNCPrefix;
        //remove the leading \\
        directory = directory.Substring(2);
      }

      try
      {
        findHandle = FindFirstFile(prefix + directory + @"\*", out findData);
        if (findHandle != INVALID_HANDLE_VALUE)
        {
          do
          {
            //only pick up files
            if ((findData.dwFileAttributes & (uint)FileAttributes.Directory) == 0)
            {
              if (includeSystemAndHidden ||
                  (findData.dwFileAttributes & ((uint)FileAttributes.Hidden | (uint)FileAttributes.System)) == 0)
              {
                FileInformation fileInfo = new FileInformation();
                long ftCreationTime = (((long)findData.ftCreationTime.dwHighDateTime) << 32) +
                                      findData.ftCreationTime.dwLowDateTime;
                long ftLastWriteTime = (((long)findData.ftLastWriteTime.dwHighDateTime) << 32) +
                                       findData.ftLastWriteTime.dwLowDateTime;
                fileInfo.Name = Path.Combine(directory, findData.cFileName);
                if (prefix == UNCPrefix) fileInfo.Name = @"\\" + fileInfo.Name;
                fileInfo.Length = (((long)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
                fileInfo.CreationTime = DateTime.FromFileTimeUtc(ftCreationTime);
                fileInfo.ModificationTime = DateTime.FromFileTimeUtc(ftLastWriteTime);
                fi.Add(fileInfo);
              }
            }
          } while (FindNextFile(findHandle, out findData));
          FindClose(findHandle);
          findHandle = IntPtr.Zero;
        }
      }
      finally
      {
        if (findHandle.ToInt32() > 0) FindClose(findHandle);
      }
      return fi.ToArray();
    }