///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002-2026, Open Design Alliance (the "Alliance").
// All rights reserved.
// 
// This software and its documentation and related materials are owned by
// the Alliance. The software may only be incorporated into application
// programs owned by members of the Alliance, subject to a signed
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable
// trade secrets of the Alliance and its suppliers. The software is also
// protected by copyright law and international treaty provisions. Application
// programs incorporating this software must include the following statement
// with their copyright notices:
// 
//   This application incorporates Open Design Alliance software pursuant to a
//   license agreement with Open Design Alliance.
//   Open Design Alliance Copyright (C) 2002-2026 by Open Design Alliance.
//   All rights reserved.
// 
// By use of this software, its documentation or related materials, you
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////

(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('@inweb/viewer-three')) :
	typeof define === 'function' && define.amd ? define(['@inweb/viewer-three'], factory) :
	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ODA.Three));
})(this, (function (viewerThree) { 'use strict';

	var Stats = function () {
		var mode = 0;
		var container = document.createElement( 'div' );
		container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';
		container.addEventListener( 'click', function ( event ) {
			event.preventDefault();
			showPanel( ++ mode % container.children.length );
		}, false );
		function addPanel( panel ) {
			container.appendChild( panel.dom );
			return panel;
		}
		function showPanel( id ) {
			for ( var i = 0; i < container.children.length; i ++ ) {
				container.children[ i ].style.display = i === id ? 'block' : 'none';
			}
			mode = id;
		}
		var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;
		var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) );
		var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) );
		if ( self.performance && self.performance.memory ) {
			var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) );
		}
		showPanel( 0 );
		return {
			REVISION: 16,
			dom: container,
			addPanel: addPanel,
			showPanel: showPanel,
			begin: function () {
				beginTime = ( performance || Date ).now();
			},
			end: function () {
				frames ++;
				var time = ( performance || Date ).now();
				msPanel.update( time - beginTime, 200 );
				if ( time >= prevTime + 1000 ) {
					fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 );
					prevTime = time;
					frames = 0;
					if ( memPanel ) {
						var memory = performance.memory;
						memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );
					}
				}
				return time;
			},
			update: function () {
				beginTime = this.end();
			},
			domElement: container,
			setMode: showPanel
		};
	};
	Stats.Panel = function ( name, fg, bg ) {
		var min = Infinity, max = 0, round = Math.round;
		var PR = round( window.devicePixelRatio || 1 );
		var WIDTH = 80 * PR, HEIGHT = 48 * PR,
			TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
			GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
			GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
		var canvas = document.createElement( 'canvas' );
		canvas.width = WIDTH;
		canvas.height = HEIGHT;
		canvas.style.cssText = 'width:80px;height:48px';
		var context = canvas.getContext( '2d' );
		context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';
		context.textBaseline = 'top';
		context.fillStyle = bg;
		context.fillRect( 0, 0, WIDTH, HEIGHT );
		context.fillStyle = fg;
		context.fillText( name, TEXT_X, TEXT_Y );
		context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
		context.fillStyle = bg;
		context.globalAlpha = 0.9;
		context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
		return {
			dom: canvas,
			update: function ( value, maxValue ) {
				min = Math.min( min, value );
				max = Math.max( max, value );
				context.fillStyle = bg;
				context.globalAlpha = 1;
				context.fillRect( 0, 0, WIDTH, GRAPH_Y );
				context.fillStyle = fg;
				context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );
				context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );
				context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );
				context.fillStyle = bg;
				context.globalAlpha = 0.9;
				context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );
			}
		};
	};

	class StatsPanelComponent {
	    constructor(viewer) {
	        this.updateStats = () => {
	            this.stats.update();
	        };
	        this.updateViewer = () => {
	            this.viewer.update();
	        };
	        this.stats = new Stats();
	        this.stats.dom.style.position = "absolute";
	        this.stats.dom.style.left = "0px";
	        this.stats.dom.style.top = "0px";
	        viewer.canvas.parentElement.appendChild(this.stats.dom);
	        this.viewer = viewer;
	        this.viewer.addEventListener("render", this.updateStats);
	        this.viewer.addEventListener("animate", this.updateViewer);
	    }
	    dispose() {
	        this.viewer.removeEventListener("render", this.updateStats);
	        this.viewer.removeEventListener("animate", this.updateViewer);
	        this.stats.dom.remove();
	    }
	}
	viewerThree.components.registerComponent("StatsPanelComponent", (viewer) => new StatsPanelComponent(viewer));

}));
//# sourceMappingURL=StatsPanelComponent.js.map
