var GraphicViewerStatics = {};
GraphicViewerStatics.ItemHeight = 80;
class GraphicViewerItem extends Engine.Drawable
{
	constructor()
	{
		super();
		this.updateTimer = new Engine.SimpleTimer();
		
		this.graphic = new Engine.UniformScaleGraphic(GraphicViewerStatics.ItemHeight - 10, GraphicViewerStatics.ItemHeight - 30, 3);
		this.graphic.x = 5; this.graphic.y = 5;

		this.name = new Engine.DrawableText();
		this.name.x = 5;
		this.name.y = GraphicViewerStatics.ItemHeight - 20;

		this.addChild(this.graphic);
		this.addChild(this.name);

		this.mouseEnabled = true;
		this.hitArea = new PIXI.Rectangle(0, 0, 200, GraphicViewerStatics.ItemHeight);

		this.onClick = null;

		this.events.onClick.addListener(this, this.clicked);
	}

	clicked()
	{
		if (this.onClick) this.onClick(this.graphicDef);
	}

	init(graphicDef)
	{
		this.clear();
		this.graphicDef = graphicDef;
		this.updateTimer.start(0.3, this.update.bind(this));
		this.name.setText((graphicDef.id == -1 ? "" : "(" + graphicDef.id + ") ") + graphicDef.name, "Verdana", 9);
	}
	update()
	{
		this.graphic.setGraphicByName(this.graphicDef.name);
	}
	clear()
	{
		this.updateTimer.stop();
		this.graphic.clear();
	}
}
class GraphicViewer extends Engine.Dialog
{
    //public delegate void MessageBoxCallback(bool doSomething);
    constructor(parentClip /*Drawable*/)
    {
        super(parentClip);

        this.name = "GraphicViewer";

        this.boxWidth = 1000;
        this.boxHeight = 600;

        this.callbackFunction = null;
        
        this.background = new ShardsStyleDialogBackground();
        this.background.init(this.boxWidth, this.boxHeight, "Graphics", () => { this.closeClicked();} );

        this.addChild(this.background);

        this.clickBackgroundToClose = true;

        this.dialogWidth = this.boxWidth;
        this.dialogHeight = this.boxHeight;

		this.scrollPool = new Engine.ObjectPool(GraphicViewerItem);

		this.graphicWindow = new Engine.ScrollWindow();
		this.graphicWindow.displayItemSource = (data) => this.getGraphicScrollItem(data);
		this.graphicWindow.displayItemReturn = (item) => this.returnGraphicScrollItem(item);
		
		this.graphicWindow.x = 25;
		this.graphicWindow.y = 40;
		this.graphicWindow.layout(200, this.boxHeight - 50, 1);

		this.graphicWindow.scrollPane.onScroll.addListener(this, this.paneScrolled);

		this.addChild(this.graphicWindow);

		this.updateFilterTimer = new Engine.SimpleTimer();

		this.filterHolder = document.createElement("div");
		this.filterHolder.innerHTML = "<input type=text id=graphicFilter placeholder='Graphic Filter' style='width:100%'>";
		this.filterText = getChildById(this.filterHolder, "graphicFilter");
		this.filterText.onfocus = () => KeyboardManager.disable();
		this.filterText.onblur = () => KeyboardManager.enable();

		this.filterHolder.style.position = "absolute";
		this.filterHolder.style.padding = "4px 4px 4px 4px";
		this.filterHolder.style.backgroundColor = "#000000";
		this.filterHolder.style.width = "400px";

		this.graphicDefsToShow = [];
		this.scrollIndex = 0;
		this.scrollContinuePercent = 0.8;
		this.initScroll(true);

		this.filterText.onchange = () => this.filterChanged();
		this.filterText.oninput = () => this.filterChanged();

		this.graphic = new Engine.Drawable();
		this.addChild(this.graphic);


		this.playButton = new Engine.DrawableButton("Button_SimpleGreen", "|>");
		this.playButton.setDimensions(30, 30);
		this.playButton.onClick = () => this.clickedPlay();

		this.nextSequenceButton = new Engine.DrawableButton("Button_SimpleGreen", ">>");
		this.nextSequenceButton.setDimensions(30, 30);
		this.nextSequenceButton.onClick = () => this.clickedNextSequence();

		this.prevSequenceButton = new Engine.DrawableButton("Button_SimpleGreen", "<<");
		this.prevSequenceButton.setDimensions(30, 30);
		this.prevSequenceButton.onClick = () => this.clickedPrevSequence();
		
		this.addChild(this.playButton);
		this.addChild(this.nextSequenceButton);
		this.addChild(this.prevSequenceButton);

		this.frameText = new Engine.DrawableText();
		this.addChild(this.frameText);

        this.layout(this.boxWidth, this.boxHeight);

		this.showDef(null);
    }

	clickedPlay(forcePlayStop = undefined)
	{
		if (this.graphic.playing || forcePlayStop === false)
		{
			this.graphic.stop();
			this.playButton.setButtonText("|>");
			this.playButton.setDimensions(30, 30);
			this.playButton.enabled = this.graphic.numFrames > 1;
		}
		else if (!this.graphic.playing || forcePlayStop === true)
		{
			this.graphic.play();
			this.playButton.setButtonText("||");
			this.playButton.setDimensions(30, 30);
		}
	}

	clickedPrevSequence()
	{
		this.graphic.setSequence((this.graphic.sequence - 1 + this.graphics.numSequences) % this.graphic.numSequences);
		this.playButton.enabled = this.graphic.numFrames > 1;
	}

	clickedNextSequence()
	{
		this.graphic.setSequence((this.graphic.sequence + 1) % this.graphic.numSequences);
		this.playButton.enabled = this.graphic.numFrames > 1;
	}

	paneScrolled()
	{
		let scrollHeight = this.graphicWindow.scrollPane.getScrollHeight();
		if (this.scrollIndex < this.graphicDefsToShow.length && this.graphicWindow.scrollPane.currentScrollAmount >= scrollHeight * this.scrollContinuePercent)
		{
			this.initScroll(false);
			this.graphicWindow.scrollPane.setScrollPercentFromScrollAmount();
			this.graphicWindow.scrollBar.updateScrollPos();
			this.graphicWindow.scrollBar.beginDragScroll();
			this.scrollContinuePercent = 1 - (1 - this.scrollContinuePercent) * 0.9;
		}
	}

	initScroll(resetScroll)
	{
		if (resetScroll)
		{
			this.scrollContinuePercent = 0.8;
			this.graphicWindow.clear();
			this.scrollIndex = 0;

			let filter = this.filterText.value.toLowerCase().trim();

			let filterNum = 0;
			if (filter.length == 0)
			{
				filter = null;
			}
			else
			{
				filterNum = parseInt(filter);
				try
				{
					filter = new RegExp(filter, "gi");
				} catch
				{
					filter = null;
				}
			}

			this.graphicDefsToShow = Object.values(Engine.GraphicFactoryInstance.graphicDataByName).sort((a, b) => a.id - b.id).filter(
				g => !filter || filter.test(g.name.toLowerCase()) || filterNum == g.id
			);
		}

		let limit = Math.min(this.scrollIndex + 2500, this.graphicDefsToShow.length);
		for (let i = this.scrollIndex; i < limit; i++)
		{
			this.scrollIndex++;
			this.graphicWindow.addItem(this.graphicDefsToShow[i], 200, GraphicViewerStatics.ItemHeight);
		}
	}

	filterChanged()
	{
		this.updateFilterTimer.start(0.25, () => this.filterUpdated());
	}

	filterUpdated()
	{
		this.initScroll(true);
	}

	positionFilter()
	{
		let loc = this.localToGlobal(new Vector2(300, 60));
		this.filterHolder.style.left = loc.x + "px";
		this.filterHolder.style.top = loc.y + "px";
	}

	getGraphicScrollItem(graphicDef)
	{
		let item = this.scrollPool.getNextObject();
		item.init(graphicDef);
		item.onClick = this.clickedItem.bind(this);
		return item;
	}

	clickedItem(graphicDef)
	{
		this.showDef(graphicDef);
	}

	showDef(graphicDef)
	{
		if (graphicDef)
		{
			this.graphic.loadFromGraphicName(graphicDef.name);
			this.graphic.setSequence(0);
			this.graphic.gotoAndStop(0);
			this.clickedPlay(false);
			this.prevSequenceButton.enabled = this.graphic.numSequences > 1;
			this.nextSequenceButton.enabled = this.graphic.numSequences > 1;
		}
		else
		{
			this.graphic.clearSprite();
			this.playButton.setButtonText("|>");
			this.playButton.setDimensions(30, 30);
			this.prevSequenceButton.enabled = false;
			this.nextSequenceButton.enabled = false;
		}
	}

	returnGraphicScrollItem(item)
	{
		item.clear();
		this.scrollPool.returnObject(item);
	}

    closeClicked()
    {
        this.hide();
    }

    show()
    {
        this.active = true;
        this.parentClip.addChild(this);

        this.layout(this.boxWidth, this.boxHeight);
		this.showDef(null);
        this.showDialog();
    }

	update(timeElapsed)
	{
		super.update(timeElapsed);

		if (this.graphic.graphicData)
		{
			let id = this.graphic.graphicData.id;
			this.frameText.setText((id == -1 ? "" : "(" + id + ") ") + this.graphic.graphicData.name + "\nSeq " + this.graphic.sequence + " / " + this.graphic.numSequences + "    Frame: " + this.graphic.frame + " / " + this.graphic.numFrames);
		}
		else
		{
			this.frameText.setText("");
		}
	}

	finishSlide()
	{
		super.finishSlide();

		document.body.appendChild(this.filterHolder);
		this.positionFilter();
	}

    layout(width, height)
    {
        this.boxWidth = width;
        this.boxHeight = height;

        this.background.layout(this.boxWidth, this.boxHeight);

		this.graphic.y = height - 150;
		this.graphic.x = (width - 200) * 0.5 + 200;

		this.playButton.x = (width - 200) * 0.5 + 185;
		this.nextSequenceButton.x = this.playButton.x + 35;
		this.prevSequenceButton.x = this.playButton.x - 35;
		this.playButton.y = this.nextSequenceButton.y = this.prevSequenceButton.y = height - 50;

		this.frameText.x = 240;
		this.frameText.y = height - 60;
    }

    hide(instant /*bool*/)
    {
        super.hide(instant);
		document.body.removeChild(this.filterHolder);
    }
}
