(function() { 'use strict'; // ========================================================================= // AGGREGATE ALL CONTEXTS // ========================================================================= var ALL_CONTEXTS = []; // Add vehicle contexts if (window.VehicleContexts) { VehicleContexts.getAll().forEach(function(ctx) { ALL_CONTEXTS.push(ctx); }); } // Add costume contexts if (window.CostumeContexts) { CostumeContexts.getAll().forEach(function(ctx) { ALL_CONTEXTS.push(ctx); }); } // Add pure contexts if (window.PureContexts) { PureContexts.getAll().forEach(function(ctx) { ALL_CONTEXTS.push(ctx); }); } // Create lookup map var CONTEXT_MAP = {}; ALL_CONTEXTS.forEach(function(ctx) { CONTEXT_MAP[ctx.id] = ctx; }); // ========================================================================= // CATEGORY METADATA // ========================================================================= var CATEGORIES = { vehicle: { id: 'vehicle', name: 'Vehicles', description: 'Place your avatar in vehicles and cockpits', icon: '🚗', count: 0 // calculated }, costume: { id: 'costume', name: 'Costumes', description: 'Dress your avatar in themed outfits', icon: '👔', count: 0 }, pure: { id: 'pure', name: 'Standard', description: 'Your avatar with minimal modifications', icon: '🏃', count: 0 } }; // Count per category ALL_CONTEXTS.forEach(function(ctx) { if (CATEGORIES[ctx.category]) { CATEGORIES[ctx.category].count++; } }); // ========================================================================= // GAME TYPE MAPPINGS // ========================================================================= var GAME_TYPE_CONTEXTS = { platformer: ['platformer-standard', 'adventure-hero', 'knight-armor', 'ninja-outfit', 'superhero-cape'], racing: ['race-car', 'motorcycle', 'hoverboard', 'airplane'], shooter: ['spaceship-cockpit', 'tank', 'mech-suit', 'space-suit'], flying: ['flappy-style', 'airplane', 'jetpack', 'dragon-rider'], arcade: ['pacman-style', 'flappy-style', 'spaceship-cockpit', 'runner'], rpg: ['knight-armor', 'wizard-robes', 'ninja-outfit', 'pirate-outfit', 'adventure-hero'], sports: ['sports-player', 'athlete-uniform', 'runner'], puzzle: ['scientist-labcoat', 'wizard-robes', 'platformer-standard'], adventure: ['adventure-hero', 'pirate-outfit', 'cowboy-gear', 'dragon-rider'], action: ['superhero-cape', 'ninja-outfit', 'mech-suit', 'jetpack'], underwater: ['submarine', 'space-suit'], space: ['spaceship-cockpit', 'space-suit', 'mech-suit'], cooking: ['chef-outfit'], simulation: ['airplane', 'submarine', 'race-car', 'tank'] }; // ========================================================================= // MODE GROUPINGS // ========================================================================= var MODE_CONTEXTS = { HEAD_ONLY: [], HEAD_AND_SHOULDERS: [], UPPER_BODY: [], FULL_BODY: [] }; ALL_CONTEXTS.forEach(function(ctx) { if (MODE_CONTEXTS[ctx.avatarMode]) { MODE_CONTEXTS[ctx.avatarMode].push(ctx.id); } }); // ========================================================================= // CATALOG STATISTICS // ========================================================================= var STATS = { totalContexts: ALL_CONTEXTS.length, vehicleCount: CATEGORIES.vehicle.count, costumeCount: CATEGORIES.costume.count, pureCount: CATEGORIES.pure.count, version: '1.0.0', lastUpdated: '2026-02-05' }; // ========================================================================= // PUBLIC API // ========================================================================= window.ContextCatalog = { // Core getters getAll: function() { return ALL_CONTEXTS.slice(); }, getById: function(id) { return CONTEXT_MAP[id] || null; }, // Category queries getByCategory: function(category) { return ALL_CONTEXTS.filter(function(ctx) { return ctx.category === category; }); }, getCategories: function() { return Object.values(CATEGORIES); }, getCategoryInfo: function(categoryId) { return CATEGORIES[categoryId] || null; }, // Mode queries getByMode: function(mode) { var ids = MODE_CONTEXTS[mode] || []; return ids.map(function(id) { return CONTEXT_MAP[id]; }).filter(Boolean); }, getModes: function() { return Object.keys(MODE_CONTEXTS); }, // Game type recommendations getRecommendedFor: function(gameType) { var ids = GAME_TYPE_CONTEXTS[gameType] || []; return ids.map(function(id) { return CONTEXT_MAP[id]; }).filter(Boolean); }, getGameTypes: function() { return Object.keys(GAME_TYPE_CONTEXTS); }, // Search/filter search: function(query) { query = query.toLowerCase(); return ALL_CONTEXTS.filter(function(ctx) { return ctx.id.toLowerCase().includes(query) || ctx.name.toLowerCase().includes(query) || ctx.description.toLowerCase().includes(query); }); }, filter: function(filters) { return ALL_CONTEXTS.filter(function(ctx) { if (filters.category && ctx.category !== filters.category) return false; if (filters.mode && ctx.avatarMode !== filters.mode) return false; if (filters.gameType) { var recommended = GAME_TYPE_CONTEXTS[filters.gameType] || []; if (recommended.indexOf(ctx.id) === -1) return false; } return true; }); }, // For UI display getCatalogForUI: function() { return { categories: Object.values(CATEGORIES).map(function(cat) { return { id: cat.id, name: cat.name, description: cat.description, icon: cat.icon, contexts: ALL_CONTEXTS.filter(function(ctx) { return ctx.category === cat.id; }).map(function(ctx) { return { id: ctx.id, name: ctx.name, description: ctx.description, mode: ctx.avatarMode, recommendedFor: ctx.recommendedFor }; }) }; }) }; }, // Random selection getRandom: function(filters) { var pool = filters ? this.filter(filters) : ALL_CONTEXTS; if (pool.length === 0) return null; return pool[Math.floor(Math.random() * pool.length)]; }, getRandomForGameType: function(gameType) { var recommended = this.getRecommendedFor(gameType); if (recommended.length === 0) return null; return recommended[Math.floor(Math.random() * recommended.length)]; }, // Statistics getStats: function() { return Object.assign({}, STATS); }, // Validation validate: function() { var issues = []; ALL_CONTEXTS.forEach(function(ctx) { if (!ctx.id) issues.push('Context missing id'); if (!ctx.name) issues.push(ctx.id + ': missing name'); if (!ctx.avatarMode) issues.push(ctx.id + ': missing avatarMode'); if (!ctx.category) issues.push(ctx.id + ': missing category'); if (!ctx.animations || ctx.animations.length === 0) { issues.push(ctx.id + ': missing animations'); } }); return { valid: issues.length === 0, issues: issues }; } }; })();