public bool CurrentItemMove(bool next) {
   LoadSiblings();
   if (Current == null) return false;
   var newIndex = next ? Current.Index + 1 : Current.Index - 1;
   if (newIndex < 0 || newIndex >= Items.Count) return false;
   Current.IsSelected = false;
   Current = Items[newIndex];
   Current.IsSelected = true;
   return true;
 }
    private void ProcessDirectory(string path, BackgroundWorker worker) {
      try {
        foreach (var dir in Directory.EnumerateDirectories(path)) {
          if (worker.CancellationPending) return;
          ProcessDirectory(dir, worker);
        }
      }
      catch (Exception) {
        // ignored
      }

      try {
        var dirId = _aCore.Db.InsertDirecotryInToDb(path);

        foreach (var file in Directory.EnumerateFiles(path)
          .Where(f => _aCore.MediaItems.SuportedExts.Any(x => f.EndsWith(x, StringComparison.OrdinalIgnoreCase)))
          .OrderBy(x => x)) {

          var miInDb = _aCore.Db.MediaItems.SingleOrDefault(x => x.DirectoryId == dirId && x.FileName == Path.GetFileName(file));
          var mi = new ViewModel.BaseMediaItem(file, 0, miInDb) {DirId = dirId};
          if (!_newOnly || miInDb == null)
            mi.SaveMediaItemInToDb(true, miInDb == null);

          if (_rebuildThumbnails || !File.Exists(mi.FilePathCache))
            AppCore.CreateThumbnail(mi.FilePath, mi.FilePathCache);

          _filesDone++;

          worker.ReportProgress(Convert.ToInt32(((double)_filesDone / _filesCount) * 100));
        }
        //worker.ReportProgress(Convert.ToInt32(((double)_filesDone / _filesCount) * 100), true);
      }
      catch (Exception ex) {
        // ignored
      }
    }
    public void LoadByFolder(string path) {
      if (!Directory.Exists(path)) return;
      var maxDirId = ACore.Db.GetMaxIdFor<DataModel.Directory>();
      var dirId = ACore.Db.InsertDirecotryInToDb(path);
      if (dirId > maxDirId) ACore.FolderKeywords.Load();
      FolderKeyword fk = ACore.FolderKeywords.GetFolderKeywordByFullPath(path);

      Current = null;
      Items.Clear();

      var dbItems = new List<DataModel.MediaItem>();
      var dbItemsByDir = ACore.Db.MediaItems.Where(x => x.DirectoryId == dirId).ToDictionary(x => x.FileName);
      var chosenRatings = ACore.Ratings.Items.Where(x => x.BgBrush == BgBrushes.Chosen).Cast<Rating>().ToArray();

      foreach (var file in Directory.EnumerateFiles(path)
        .Where(f => SuportedExts.Any(x => f.EndsWith(x, StringComparison.OrdinalIgnoreCase)))
        .OrderBy(x => x)) {

        var filePath = file.Replace(":\\\\", ":\\");

        //Filter by Viewer
        if (!ACore.CanViewerSeeThisFile(filePath)) continue;

        DataModel.MediaItem item;
        if (dbItemsByDir.TryGetValue(Path.GetFileName(file), out item)) {
          //Filter by Rating
          if (chosenRatings.Any() && !chosenRatings.Any(x => x.Value.Equals(item.Rating))) continue;

          dbItems.Add(item);
        }

        var pic = new Picture(filePath, Items.Count, item) {
          DirId = dirId,
          FolderKeyword = fk
        };
        Items.Add(pic);
      }

      //Load People and Keywords for thous that are already in DB
      var mips = (from mip in ACore.Db.MediaItemPeople
                  join mi in dbItems on mip.MediaItemId equals mi.Id
                  select mip).ToArray();

      var miks = (from mik in ACore.Db.MediaItemKeywords
                  join mi in dbItems on mik.MediaItemId equals mi.Id
                  select mik).ToArray();

      foreach (var item in Items.Where(x => x.Data != null)) {
        //Load People
        foreach (var mip in mips.Where(x => x.MediaItemId == item.Id)) {
          item.People.Add(ACore.People.GetPerson(mip.PersonId));
        }
        //Load Keywords
        foreach (var mik in miks.Where(x => x.MediaItemId == item.Id)) {
          item.Keywords.Add(ACore.Keywords.GetKeyword(mik.KeywordId));
        }
      }

      ACore.UpdateStatusBarInfo();
    }
 public void SetCurrent() {
   var mis = Items.Where(x => x.IsSelected).ToList();
   Current = mis.Count == 1 ? mis[0] : null;
 }
 public void DeselectAll() {
   foreach (var mi in Items.Where(x => x.IsSelected)) {
     mi.IsSelected = false;
   }
   Current = null;
 }
    public void LoadByTag(BaseTreeViewTagItem tag, bool recursive) {
      if (tag == null) return;
      Current = null;
      Items.Clear();

      DataModel.MediaItem[] items = null;

      switch (tag.GetType().Name) {
        case nameof(Keyword): {
            var keyword = (Keyword)tag;
            if (recursive) {
              items = (from k in ACore.Db.Keywords.Where(x => x.Name.StartsWith(keyword.FullPath))
                       join mik in ACore.Db.MediaItemKeywords on k.Id equals mik.KeywordId into keywords
                       from k2 in keywords
                       join mi in ACore.Db.MediaItems on k2.MediaItemId equals mi.Id
                       select mi).ToList().Distinct().ToArray();
            } else {
              items = (from mi in ACore.Db.MediaItems
                       join mik in ACore.Db.MediaItemKeywords.Where(x => x.KeywordId == keyword.Id) on mi.Id equals mik.MediaItemId
                       select mi).ToArray();
            }
            break;
          }
        case nameof(Person): {
            var person = (Person)tag;
            items = (from mi in ACore.Db.MediaItems
                     join mip in ACore.Db.MediaItemPeople.Where(x => x.PersonId == person.Id) on mi.Id equals mip.MediaItemId
                     select mi).ToArray();
            break;
          }
        case nameof(FolderKeyword): {
            var folderKeyword = (FolderKeyword)tag;
            if (recursive) {
              var itemss = new List<DataModel.MediaItem>();
              foreach (var fkDir in ACore.Db.Directories.Where(x => folderKeyword.FolderIdList.Contains(x.Id))) {
                foreach (var dir in ACore.Db.Directories.Where(x => x.Path.StartsWith(fkDir.Path))) {
                  foreach (var mi in ACore.Db.MediaItems.Where(x => x.DirectoryId == dir.Id)) {
                    itemss.Add(mi);
                  }
                }
              }
              items = itemss.OrderBy(x => x.FileName).ToArray();
            } else {
              items = ACore.Db.MediaItems.Where(x => folderKeyword.FolderIdList.Contains(x.DirectoryId)).ToArray();
            }
            break;
          }
      }

      if (items != null) {
        var chosenRatings = ACore.Ratings.Items.Where(x => x.BgBrush == BgBrushes.Chosen).Cast<Rating>().ToArray();
        if (chosenRatings.Any())
          items = items.Where(i => chosenRatings.Any(x => x.Value.Equals(i.Rating))).ToArray();

        var allDirs = (from d in ACore.Db.Directories
                       join mi in items on d.Id equals mi.DirectoryId
                       select d).Distinct().ToArray();
        var dirs = allDirs.Where(dir => Directory.Exists(dir.Path)).ToDictionary(dir => dir.Id);

        var mips = (from mip in ACore.Db.MediaItemPeople
                    join mi in items on mip.MediaItemId equals mi.Id
                    select mip).ToArray();

        var miks = (from mik in ACore.Db.MediaItemKeywords
                    join mi in items on mik.MediaItemId equals mi.Id
                    select mik).ToArray();

        foreach (var item in items.OrderBy(x => x.FileName)) {
          if (!dirs.ContainsKey(item.DirectoryId)) continue;
          var filePath = Path.Combine(dirs[item.DirectoryId].Path, item.FileName);
          if (!File.Exists(filePath)) continue;

          //Filter by Viewer
          if (!ACore.CanViewerSeeThisFile(filePath)) continue;

          Picture pic = new Picture(filePath, Items.Count, item);
          //Load People
          foreach (var mip in mips.Where(x => x.MediaItemId == item.Id)) {
            pic.People.Add(ACore.People.GetPerson(mip.PersonId));
          }
          //Load Keywords
          foreach (var mik in miks.Where(x => x.MediaItemId == item.Id)) {
            pic.Keywords.Add(ACore.Keywords.GetKeyword(mik.KeywordId));
          }
          //Folder Keyword
          pic.FolderKeyword = ACore.FolderKeywords.GetFolderKeywordByFullPath(Path.GetDirectoryName(filePath));

          //TODO docasne, pak odstranit
          var viewer = ACore.Viewers.Items.Cast<Viewer>().SingleOrDefault(x => x.Title == Settings.Default.Viewer);
          if (viewer != null && viewer.Title.Equals("Prezentace")) {
            if (pic.Keywords.Any(x => x.FullPath.StartsWith("#CoSpi/Weed"))) continue;
          }

          Items.Add(pic);
        }
      }

      ACore.UpdateStatusBarInfo();
    }