import { EventEmitter } from '$lib/utils/EventEmitter'; export interface MudProfile { id: string; name: string; host: string; port: number; useSSL: boolean; autoLogin?: { enabled: boolean; username: string; password: string; commands: string[]; }; triggers?: string; // JSON string of triggers aliases?: { [key: string]: string; }; macros?: { [key: string]: string; }; gmcpPackages?: string[]; // Additional GMCP packages to support font?: string; fontSize?: number; theme?: string; ansiColor: boolean; accessibilityOptions?: { textToSpeech: boolean; highContrast: boolean; speechRate: number; speechPitch: number; speechVolume: number; }; } export class ProfileManager extends EventEmitter { private profiles: MudProfile[] = []; private activeProfileId: string | null = null; private storageKey = 'svelte-mud-profiles'; constructor() { super(); this.loadProfiles(); } /** * Load profiles from local storage */ private loadProfiles(): void { if (typeof window === 'undefined') { return; // Skip during SSR } try { const storedProfiles = localStorage.getItem(this.storageKey); if (storedProfiles) { this.profiles = JSON.parse(storedProfiles); console.log('Loaded profiles from localStorage:', this.profiles); this.emit('profilesLoaded', this.profiles); } else { console.log('No profiles found in localStorage, creating default profile'); // Add a default profile if none exist const defaultProfile = this.createDefaultProfile(); defaultProfile.name = 'Aardwolf MUD'; defaultProfile.host = 'aardmud.org'; defaultProfile.port = 23; this.addProfile(defaultProfile); } } catch (error) { console.error('Failed to load profiles from local storage:', error); // Add a default profile if there was an error const defaultProfile = this.createDefaultProfile(); defaultProfile.name = 'Aardwolf MUD'; defaultProfile.host = 'aardmud.org'; defaultProfile.port = 23; this.addProfile(defaultProfile); } } /** * Save profiles to local storage */ private saveProfiles(): void { if (typeof window === 'undefined') { return; // Skip during SSR } try { localStorage.setItem(this.storageKey, JSON.stringify(this.profiles)); } catch (error) { console.error('Failed to save profiles to local storage:', error); } } /** * Add a new profile */ public addProfile(profile: MudProfile): void { // Ensure all required fields are present if (!profile.id) { profile.id = `profile-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; } if (profile.useSSL === undefined) { profile.useSSL = false; } if (profile.ansiColor === undefined) { profile.ansiColor = true; } // Check if a profile with the same ID already exists const existingIndex = this.profiles.findIndex(p => p.id === profile.id); if (existingIndex !== -1) { // Update existing profile this.profiles[existingIndex] = profile; console.log(`Updated profile ${profile.id} (${profile.name})`, profile); this.emit('profileUpdated', profile); } else { // Add new profile this.profiles.push(profile); console.log(`Added new profile ${profile.id} (${profile.name})`, profile); this.emit('profileAdded', profile); } // Save to storage this.saveProfiles(); } /** * Remove a profile by ID */ public removeProfile(profileId: string): void { const index = this.profiles.findIndex(p => p.id === profileId); if (index !== -1) { const removedProfile = this.profiles[index]; this.profiles.splice(index, 1); // If the active profile was removed, clear the active profile if (this.activeProfileId === profileId) { this.activeProfileId = null; this.emit('activeProfileChanged', null); } this.emit('profileRemoved', removedProfile); this.saveProfiles(); } } /** * Get all profiles */ public getProfiles(): MudProfile[] { return [...this.profiles]; } /** * Get a profile by ID */ public getProfile(profileId: string): MudProfile | undefined { return this.profiles.find(p => p.id === profileId); } /** * Set the active profile */ public setActiveProfile(profileId: string): void { const profile = this.getProfile(profileId); if (profile) { this.activeProfileId = profileId; this.emit('activeProfileChanged', profile); } else { throw new Error(`Profile with ID ${profileId} not found`); } } /** * Get the active profile */ public getActiveProfile(): MudProfile | null { if (!this.activeProfileId) return null; const activeProfile = this.getProfile(this.activeProfileId); return activeProfile || null; } /** * Import profiles from a JSON string */ public importProfiles(json: string): void { try { const imported = JSON.parse(json); if (Array.isArray(imported)) { imported.forEach(profile => { if (this.isValidProfile(profile)) { this.addProfile(profile); } }); } this.emit('profilesImported', imported); } catch (error) { console.error('Failed to import profiles:', error); throw new Error('Failed to import profiles. Invalid format.'); } } /** * Export profiles to a JSON string */ public exportProfiles(): string { return JSON.stringify(this.profiles, null, 2); } /** * Validate a profile object */ private isValidProfile(obj: any): boolean { return ( typeof obj === 'object' && typeof obj.id === 'string' && typeof obj.name === 'string' && typeof obj.host === 'string' && typeof obj.port === 'number' && typeof obj.useSSL === 'boolean' && typeof obj.ansiColor === 'boolean' ); } /** * Create a default profile */ public createDefaultProfile(): MudProfile { const id = `profile-${Date.now()}`; return { id, name: 'New Profile', host: 'mud.example.com', port: 23, useSSL: false, ansiColor: true, autoLogin: { enabled: false, username: '', password: '', commands: [] }, aliases: {}, macros: {}, gmcpPackages: [], accessibilityOptions: { textToSpeech: false, highContrast: false, speechRate: 1, speechPitch: 1, speechVolume: 1 } }; } }