using System.Drawing; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using file_finder__test; using ShadowStream; using ShadowStream.LogHelper; using ShadowStream.Obejeckte; using System.IO; using System.Threading; using ShadowStream.ObjecktForJason; using TagLib; using ShadowStream.Modules; using ShadowStream.ObjecktForJason; using LibVLCSharp.Shared; using Brushes = System.Windows.Media.Brushes; using Color = System.Windows.Media.Color; using File = System.IO.File; using Image = System.Drawing.Image; using Path = System.IO.Path; namespace ModuleManager; /// /// Interaction logic for MainWindow.xaml /// //Quinn and Reda and Yazan public partial class MainWindow : Window { //quinn #region no dont cahnge //adding base components used threw out the code private static LogHelper loghelper = new LogHelper(); LogWindow logWin = new LogWindow(loghelper.GetEntries()); LogHelper log = new LogHelper(); private Catagory Muvie = new Catagory("Muvie"); private Catagory Serie = new Catagory("Serie"); private Catagory Music = new Catagory("Music"); private Catagory Photo = new Catagory("Photos"); List suportedVidioFiles = new List(); List suportedMusicFiles = new List(); List suportedPhotoFiles = new List(); //root directory List dirs = new List(); private int option =2; int specificOption = 0; string rootPath = "F:/"; FileScanner fileScanner; #endregion //Quinn #region vlc logic private LibVLC _libVLC; private LibVLCSharp.Shared.MediaPlayer _mediaPlayer; #endregion //code start public MainWindow() { #region Init wpf InitializeComponent(); //Initialise but Hide logWin.Hide(); //this.Hide(); //Begin Login Process var login = new LogIn(); login.Show(); #endregion //Quinn Dont change or remuve!!! #region vlc init Core.Initialize(); // Important: load native libvlc binaries _libVLC = new LibVLC(); _mediaPlayer = new LibVLCSharp.Shared.MediaPlayer(_libVLC); VideoView.MediaPlayer = _mediaPlayer; #endregion #region only exdend. no remuving of code //adding all extensions... example values added suportedVidioFiles.Add(".mp4"); suportedVidioFiles.Add(".mkv"); suportedMusicFiles.Add(".wav"); suportedMusicFiles.Add(".mp3"); suportedPhotoFiles.Add(".jpg"); Createscan(); //dirs.Add("C:/"); //execute and wait for task completion var tmp = fileScanner.ScanAllDrivesAsync(); //load json parallel to finding drives //add code laiter tmp.Wait(); foreach (var VARIABLE in tmp.Result) { dirs.Add(VARIABLE); } #endregion LoadSavedData(); } //Quinn #region dont change //reminder to self. if issue acures. check if anyone changed folder names #region ScannLogic void Createscan() { //adding all string arrays to one temp array to do the initial scan of the designated drive int count = 0; string[] tmp = new string[suportedMusicFiles.Count + suportedVidioFiles.Count + suportedPhotoFiles.Count]; foreach (var suportedVidioFile in suportedVidioFiles) { tmp[count] = suportedVidioFile; count++; } foreach (var suportedMusicFile in suportedMusicFiles) { tmp[count] = suportedMusicFile; count++; } foreach (var suportedPhotoFile in suportedPhotoFiles) { tmp[count] = suportedPhotoFile; count++; } //initialise the file scanner with all files endings wanted fileScanner = new FileScanner(tmp); } #endregion #region Click Methods private void OnItemPlayButtonClick(object sender, RoutedEventArgs e) { if (sender is Button btn && btn.Tag is string filePath) { if (filePath.EndsWith(".jpg") || filePath.EndsWith(".png")) { ShowImageWithVLC(filePath); // you'd implement this } else { PlayVideo(filePath); } } } private void Close_Player(object sender, RoutedEventArgs e) { _mediaPlayer.Stop(); VideoView.Visibility = Visibility.Collapsed; } void Video_Click(object sender, RoutedEventArgs e) { PlayVideo(@"F:\Rio.mp4"); } private async void scanButton_Click(object sender, RoutedEventArgs e) { try { Muvie.clear(); Serie.clear(); Music.clear(); Photo.clear(); log.Log("Scanning files..."); List tmp = new List(); switch (option) { case 0: foreach (var VARIABLE in dirs) { foreach (var tmp2 in await fileScanner.ScanDriveParallel(VARIABLE)) { tmp.Add(tmp2); } } break; case 1: foreach (var VARIABLE in await fileScanner.ScanDriveParallel(dirs[specificOption])) { tmp.Add(VARIABLE); } break; case 2: foreach (var VARIABLE in await fileScanner.ScanDriveParallel(rootPath)) { tmp.Add(VARIABLE); } break; } log.Log($"Total scanned files: {tmp.Count}"); var classifier = new FileClassifier(); var (musicFiles, videoFiles, photoFiles) = await classifier.ClassifyFilesAsync(tmp, suportedMusicFiles, suportedVidioFiles, suportedPhotoFiles); var separator = new VideoSeparator(); var (series, movies) = await separator.SeparateVideosAsync(videoFiles); log.Log($"musicFiles count: {musicFiles.Count}"); log.Log($"videoFiles count: {videoFiles.Count}"); log.Log($"photoFiles count: {photoFiles.Count}"); log.Log($"series count: {series.Count}"); log.Log($"movies count: {movies.Count}"); videoFiles = null; log.Log("files sorted"); // Prepare JSON lists List muviesJS = new List(); List seriesJS = new List(); List photosJS = new List(); List mucicJS = new List(); JasonToString jasonToString = new JasonToString(); foreach (var VARIABLE in ItemCreater(movies, "Muvie", false)) { Muvie.addItem(VARIABLE); muviesJS.Add(new locJason { path = VARIABLE.getLink(), imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())), type = VARIABLE.getType() }); } foreach (var VARIABLE in ItemCreater(series, "Serie", false)) { Serie.addItem(VARIABLE); seriesJS.Add(new locJason { path = VARIABLE.getLink(), imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())), type = VARIABLE.getType() }); } foreach (var VARIABLE in ItemCreater(photoFiles, "Photo", true)) { Photo.addItem(VARIABLE); photosJS.Add(new locJason { path = VARIABLE.getLink(), imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())), type = VARIABLE.getType() }); } foreach (var VARIABLE in ItemCreater(musicFiles, "Music", false, true)) { Music.addItem(VARIABLE); mucicJS.Add(new locJason { path = VARIABLE.getLink(), imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())), type = VARIABLE.getType() }); } log.Log("scan finished"); Jason_Writer jason_Writer = new Jason_Writer(); List tasks = new List { jason_Writer.SaveList("Muvies", muviesJS), jason_Writer.SaveList("Series", seriesJS), jason_Writer.SaveList("Photos", photosJS), jason_Writer.SaveList("Music", mucicJS) }; await Task.WhenAll(tasks); mucicJS = null; seriesJS = null; photosJS = null; MenueItems(); MessageBox.Show("Scan finished"); } catch (Exception ex) { MessageBox.Show($"An error occurred during scanning:\n\n{ex.ToString()}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); log.Error($"An error occurred during scanning:\n\n{ex.ToString()}"); } } #endregion #region itemCreation List ItemCreater(List path, string type,bool isFoto) { List items = new List(); foreach (var VARIABLE in path) { BitmapImage frame200; if(!isFoto) frame200 = VideoFrameExtractor.GetFrame200(VARIABLE); else { frame200 = new BitmapImage(new Uri(VARIABLE, UriKind.Absolute)); } items.Add(new Item(VARIABLE, type,frame200, isFoto,OnItemPlayButtonClick)); } return items; } List ItemCreater(List paths, string type, bool isFoto, bool Music) { List items = new List(); string baseDir = AppDomain.CurrentDomain.BaseDirectory; string imagePath = Path.Combine(baseDir,"Resources", "Pics", "MusicD.jpeg"); BitmapImage defaultImage; if (File.Exists(imagePath)) { defaultImage = new BitmapImage(new Uri(imagePath)); defaultImage.Freeze(); } else { //this case schould never be called. its to prevent code from breaking because of unautorised muving of musicD!! MessageBox.Show($"Default image not found at: {imagePath}"); // Create a blank 100x100 transparent BitmapImage fallback int width = 100; int height = 100; int dpi = 96; var pixelFormat = PixelFormats.Pbgra32; int rawStride = (width * pixelFormat.BitsPerPixel + 7) / 8; byte[] rawImage = new byte[rawStride * height]; // all zero = transparent var bitmap = BitmapSource.Create(width, height, dpi, dpi, pixelFormat, null, rawImage, rawStride); bitmap.Freeze(); defaultImage = new BitmapImage(); defaultImage = null; } foreach (var filePath in paths) { BitmapImage bitmapImage = defaultImage; try { var file = TagLib.File.Create(filePath); if (file.Tag.Pictures.Length > 0) { var pic = file.Tag.Pictures[0]; using (var ms = new MemoryStream(pic.Data.Data)) { var img = new BitmapImage(); img.BeginInit(); img.CacheOption = BitmapCacheOption.OnLoad; img.StreamSource = ms; img.EndInit(); img.Freeze(); bitmapImage = img; } } } catch { // keep defaultImage if anything fails } items.Add(new Item(filePath, type, bitmapImage, isFoto,OnItemPlayButtonClick)); } return items; } #endregion #region Comunication public void ReciveErrorLog(string logMessage) { log.Error(logMessage); } public void PlayVideo(string filePath) { if(suportedVidioFiles.Contains(Path.GetExtension(filePath))) VideoView.Visibility = Visibility.Visible; var media = new Media(_libVLC, filePath, FromType.FromPath); _mediaPlayer.Play(media); } public void ShowImageWithVLC(string filePath) { if (File.Exists(filePath)) { VideoView.Visibility = Visibility.Visible; var media = new Media(_libVLC, filePath, FromType.FromPath); _mediaPlayer.Play(media); } } #endregion #endregion #region HomeMenue void MenueItems() { PopulatePanelWithItems(Muvie.getAllItems(), Muvies_Home); PopulatePanelWithItems(Serie.getAllItems(), Series_Home); PopulatePanelWithItems(Photo.getAllItems(), Photos_Home); PopulatePanelWithItems(Music.getAllItems(), Music_Home); } #endregion #region PanelPop private void PopulatePanelWithItems(List items, Panel targetPanel) { targetPanel.Children.Clear(); foreach (var item in items) { var name = item.getName(); var image = item.getImage(); var isFoto = item.getType() == "Photo"; var path = item.getLink(); var buttonText = isFoto ? "Show" : "Play"; if (image == null) continue; // Skip if image is not available // Container for stacking label, image, and button var container = new Grid { Width = 150, Height = 120, Margin = new Thickness(5) }; // Define rows for layout container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); // Image container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) }); // Button // Image var imgControl = new System.Windows.Controls.Image { Source = image, Width = 150, Height = 90, Stretch = Stretch.UniformToFill }; Grid.SetRow(imgControl, 0); container.Children.Add(imgControl); // Label (overlays top-left, optional) var label = new Label { Content = name, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Background = new SolidColorBrush(Color.FromArgb(180, 0, 0, 0)), Foreground = Brushes.White, Padding = new Thickness(4), FontSize = 12 }; Grid.SetRow(label, 0); container.Children.Add(label); // Button var btn = new Button { Content = buttonText, Height = 25, Width = 140, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 0, 5) }; btn.Click += (s, e) => PlayVideo(path); Grid.SetRow(btn, 1); container.Children.Add(btn); // Add to target UI panel targetPanel.Children.Add(container); } } #endregion #region load saved data private async void LoadSavedData() { try { Jason_Writer jason_Writer = new Jason_Writer(); // Use default "Temp Data" folder JasonToString jasonToString = new JasonToString(); var muvies = await jason_Writer.LoadListAsync("Muvies"); var series = await jason_Writer.LoadListAsync("Series"); var photos = await jason_Writer.LoadListAsync("Photos"); var music = await jason_Writer.LoadListAsync("Music"); List MuvieItems = CreateItemsFromJson(muvies); List SerieItems = CreateItemsFromJson(series); List PhotoItems = CreateItemsFromJson(photos, isPhoto: true); List MusicItems = CreateItemsFromJson(music, isPhoto: false, isMusic: true); Muvie.addItems(MuvieItems); Serie.addItems(SerieItems); Photo.addItems(PhotoItems); Music.addItems(MusicItems); MenueItems(); // Re-populate the UI log.Log("Loaded saved data from JSON."); } catch (Exception ex) { MessageBox.Show($"Failed to load saved data:\n{ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); log.Error($"LoadSavedData error: {ex}"); } } private List CreateItemsFromJson(List jsonItems) { return CreateItemsFromJson(jsonItems, isPhoto: false, isMusic: false); } private List CreateItemsFromJson(List jsonItems, bool isPhoto) { return CreateItemsFromJson(jsonItems, isPhoto, isMusic: false); } private List CreateItemsFromJson(List jsonItems, bool isPhoto, bool isMusic) { List items = new List(); JasonToString jasonToString = new JasonToString(); foreach (var loc in jsonItems) { BitmapImage bitmapImage = null; try { if (!string.IsNullOrEmpty(loc.imageData)) { bitmapImage = BitmapConversions.BitmapToBitmapImage( jasonToString.Base64StringToBitmap(loc.imageData) ); } else if (isMusic) { string defaultImagePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Pics", "MusicD.jpeg"); if (File.Exists(defaultImagePath)) { bitmapImage = new BitmapImage(new Uri(defaultImagePath)); bitmapImage.Freeze(); } } else if (isPhoto && File.Exists(loc.path)) { bitmapImage = new BitmapImage(new Uri(loc.path)); bitmapImage.Freeze(); } } catch { // Handle any corrupt or missing image cases } items.Add(new Item(loc.path, loc.type, bitmapImage, isPhoto, OnItemPlayButtonClick)); } return items; } #endregion }