In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

pbjLab β1.1

英語は出来ないzahirです。

ちょっと修正を施しました(6/22
 - パラメータパネルを開いた状態でもう一度同じパラメータ名をクリックするとパネルが閉じるようにした。
  - パネルを開くたびにスライダーの値が初期化されるのを修正して入力値を復元できるようにした。
 - スライダーの値を中央のTextBoxから設定できるようにした
  - inputデータが必要ない場合はその時点でshaderを実行するようにした
  - maxValue、minValueが設定されていないときに自分で設定できるようにした(復元未対応
  - Shaderの結果イメージを保存できるようにした( png or jpg( 品質 :: 90 ) )

やっていてわかったのですが
Shaderのパラメータは最低限 defaultValue を設定しないとnull扱いされてアクセスできません。
なのでバグります。気をつけてください。

パラメータとGUIがメンドクサイです。
パラメータのタイプはfloat[1~4]とint[1~4]限定です(β版なので)
matrixはめんどくさいのでやりたくないです…

ここはこうした方がいいという意見はバシバシとコメントしてください。
いつかAIRで作りたいです。
もしくは誰か作って下さい

簡単にしかテストしていないので
バグがあるかも知れませんが許してください。

今回はTextEvent.LINKを多用。
wonderflでは結構便利な感じがします。

しかし、pbjではboolを使えないのにShaderParameterType.bool[1~4]があるのは如何なもんでしょうね…
Get Adobe Flash player
by zahir 22 Jun 2009
/**
 * Copyright zahir ( http://wonderfl.net/user/zahir )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/skpS
 */

package{
	/*
	 *
	 * 英語は出来ないzahirです。
	 * 
	 *
	 *  ちょっと修正を施しました(6/22
	 *  - パラメータパネルを開いた状態でもう一度同じパラメータ名をクリックするとパネルが閉じるようにした。
	 *  - パネルを開くたびにスライダーの値が初期化されるのを修正して入力値を復元できるようにした。
	 *  - スライダーの値を中央のTextBoxから設定できるようにした
	 *  - inputデータが必要ない場合はその時点でshaderを実行するようにした
	 *  - maxValue、minValueが設定されていないときに自分で設定できるようにした(復元未対応
	 *  - Shaderの結果イメージを保存できるようにした( png or jpg( 品質 :: 90 ) )
	 *
	 *
	 *  やっていてわかったのですが
	 *  Shaderのパラメータは最低限 defaultValue を設定しないとnull扱いされてアクセスできません。
	 *  なのでバグります。気をつけてください。
	 *
	 *
	 *  パラメータとGUIがメンドクサイです。
	 *  パラメータのタイプはfloat[1~4]とint[1~4]限定です(β版なので)
	 *  matrixはめんどくさいのでやりたくないです…
	 *
	 *  ここはこうした方がいいという意見はバシバシとコメントしてください。
	 *  いつかAIRで作りたいです。
	 *  もしくは誰か作って下さい
	 *
	 *  簡単にしかテストしていないので
	 *  バグがあるかも知れませんが許してください。
	 *
	 *  今回はTextEvent.LINKを多用。
	 *  wonderflでは結構便利な感じがします。
	 *
	 *  しかし、pbjではboolを使えないのにShaderParameterType.bool[1~4]があるのは如何なもんでしょうね…
	 *
	*/
	
	import com.adobe.images.JPGEncoder;
	import com.adobe.images.PNGEncoder;
	
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shader;
	import flash.display.ShaderData;
	import flash.display.ShaderInput;
	import flash.display.ShaderJob;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TextEvent;
	import flash.geom.Matrix;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.text.TextField;
	
	[SWF(width=465, height = 465, backgroundColor = 0x666666)]
	
	public class PbjLab_beta1 extends Sprite{
		private var menu:MyMenu;
		private var subMenu:MyMenu;
		private var paramMenu:MyMenu;
		private var viewer:PBJViewer;
		private var res:ImgViewer;
		
		private var s:Shader;
		private var d:ShaderData;
		private var sj:ShaderJob;
		
		private var imgs:Array;
		private var load_img_num:int;
		private var useNum:int;
		private var side_lim:int = 240;
		private var bd:BitmapData; // Shaderを使った結果を受け取るビットマップデータ
		
		private var sliders:Array;
		private var sCon:SliderContainer;
		
		private var file:FileReference;
		private const F_FILTER_PBJ:Array = [ new FileFilter("pbj File (*.pbj)", "*.pbj") ];
		private const F_FILTER_IMG:Array = [ new FileFilter("Image File (*.jpg, *.png)", "*.jpg; *.png") ];
		
		private var w:int, h:int;
		private var cx:int, cy:int;
		
		private var first_load_flg:Boolean = false;
		private var view_flg:Boolean = false;
		private var exp_flg:Boolean = false;
		private var __set_flg:Boolean= false;
		
		public function PbjLab_beta1(){
			w = stage.stageWidth;
			h = stage.stageHeight;
			cx = w >>1;
			cy = h >>1;
			
			file = new FileReference();
			
			initMenu();
			
			Wonderfl.capture_delay(15);
		}
//  <!-- Lab
		private var _arrParam:Array;
		private var _arrImg:Array;
		
		private function iniLab():void{
			if(sCon){
				this.removeChild( sCon );
				sCon = null;
			}
			if(subMenu){
				subMenu.removeEventListener(TextEvent.LINK, onSubMenu );
				removeChild( subMenu );
				subMenu = null;
				imgs = [];
			}
			if(paramMenu){
				paramMenu.removeEventListener(TextEvent.LINK, onPMenu );
				removeChild( paramMenu);
				paramMenu = null;
				sliders = [];
			}
			var len:int, i:int;
			var input:Array = Read.inputs_data;
			var yy:int = menu.height + 1;
			if(input){
				if(!input.length){
					__set_flg = true;
					sj = new ShaderJob( s, bd, side_lim, side_lim);
					sj.start( true );
				}
				_arrImg = input;
				subMenu = new MyMenu( 0x111111, 0xCCCCCC);
				subMenu.addSeparator( 0xCC6600, "Input Images Load");
				useNum = len = input.length;
				for(i = 0; i<len; i++){
					subMenu.addSeparator( 0x0066CC, "|");
					subMenu.addMenuItem( String(i) , input[i].name);
				}
				this.addChild( subMenu );
				subMenu.y = yy;
				yy  += subMenu.height + 1;
				subMenu.addEventListener(TextEvent.LINK, onSubMenu );
				imgs = [];
			}else __set_flg = true;
			var params:Array = Read.params_data;
			if(params){
				_arrParam = params;
				paramMenu = new MyMenu( 0x111111, 0xCCCCCC );
				paramMenu.addSeparator( 0xCC6600, "Parameter's");
				len = params.length;
				sliders = [];
				for(i = 0; i<len; i++){
					paramMenu.addSeparator( 0x0, "\n");
					var a:Object= params[i] as Object;
					paramMenu.addMenuItem( i.toString() , a.name+ " : ( <font color=\"#00CC00\">" + a.type + "</font> )");
					paramMenu.addEventListener(TextEvent.LINK, onPMenu );
				}
				this.addChild( paramMenu );
				paramMenu.y = yy;
			}
		}
		private var old_p:String = "";
		private var open_flg:Boolean = false;
		
		private function onPMenu(e:TextEvent):void{
			var n:int = parseInt( e.text );
			var o:Object = _arrParam[n] as Object;
			var type:String = o.type;
			if(open_flg && old_p == o.name){
				open_flg = false;
				this.removeChild( sCon );
				sCon = null;
			}else if(open_flg && old_p != o.name){
				open_flg = true;
				old_p = o.name;
				
				if(contains(sCon)){
					removeChild( sCon );
					sCon = null;
				}
				
				paramPanelOpen(type, o.values);
			}else{
				open_flg = true;
				old_p = o.name;
				paramPanelOpen(type, o.values);
			}
		}
		
		private function paramPanelOpen( type:String, values:Vector.<Object>):void{
			if(type == "float"){
					createSlider( 1, values );
				}else if( type == "float2"){
					createSlider( 2, values );
				}else if( type == "float3"){
					createSlider( 3, values );
				}else if( type == "float4"){
					createSlider( 4, values );
				}else if( type == "int"){
					createSlider( 1, values , true);
				}else if( type == "int2"){
					createSlider( 2, values , true);
				}else if( type == "int3"){
					createSlider( 3, values , true);
				}else if( type == "int4"){
					createSlider( 4, values , true);
			}
		}
		
		private function createSlider(num:int, values:Vector.<Object>, integer:Boolean = false):void{
			sCon = new SliderContainer( num, values, this.onChange, this.d , integer );
			this.addChild( sCon );
			sCon.x = mouseX;
			sCon.y = mouseY - 5;
		}
		
		private function onSubMenu(e:TextEvent ):void{
			load_img_num = parseInt(e.text);
			onLoad_img();
		}
		
		private function onLoad_img():void{
			file = new FileReference();
			file.addEventListener(Event.SELECT, onSelect_img);
			file.browse( F_FILTER_IMG);
		}
		
		private function onSelect_img(e:Event):void{
			file.removeEventListener(Event.SELECT, onSelect_img);
			file.addEventListener(Event.COMPLETE, onComp_img );
			file.load();
		}
		
		private function onComp_img(e:Event):void{
			file.removeEventListener(Event.COMPLETE, onComp_img );
			var l:Loader = new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void{
				if(l.width > side_lim){
					l.width = side_lim, l.scaleY = l.scaleX;
				}if(l.height > side_lim){
					l.height = side_lim, l.scaleX = l.scaleY;
				}
				var m:Matrix = new Matrix();
				m.scale( l.scaleX, l.scaleY );
				imgs[ load_img_num ] = new BitmapData(l.width, l.height);
				imgs[ load_img_num ].draw( l, m );
				setInputData(_arrImg[load_img_num].name, imgs[ load_img_num ], l.width, l.height);
			});
			l.loadBytes( file.data );
		}
		
		private function setInputData( name:String, src:BitmapData , srcWidth:int, srcHeight:int):void{
			d[name].input = src;
			d[name].height = srcWidth;
			d[name].height = srcHeight;
			
			if(useNum == imgs.length){
				__set_flg = true;
				sj = new ShaderJob( s, bd, side_lim, side_lim);
				sj.start( true );
			}
		}
		private function onChange( name:String, num:String, value:Number):void{
			d[name].value[num] = value;
			if(__set_flg){
				sj = new ShaderJob( s, bd, side_lim, side_lim);
				sj.start( true );
			}
		}
//  Lab -->
//  <!-- Init Menu
		private function initMenu():void{
			menu = new MyMenu( 0x111111, 0xCCCCCC );
			menu.addEventListener(TextEvent.LINK, onMenu);
			menu.addSeparator( 0x999999, "pbjLab(β)");
			menu.addSeparator( 0x0066CC, "|");
			menu.addMenuItem( "load", "Load pbj file" );
			menu.x = menu.y = 0;
			this.addChild( menu );
		}
		
		private function onMenu( e:TextEvent ):void{
			switch(e.text){
				case "load":
					onLoad_pbj();
					break;
				case "view":
					openView();
					break;
				case "export":
					openExport();
					break;
				case "savePng":
					save();
					break;
				case "saveJpg":
					save(false);
					break;
				default : return;
			}
		}
//  Init Menu -->
//  <!--
		private function save( png:Boolean = true ):void{
			file = new FileReference();
			var date:Date = new Date();
			var str:String = String(date.fullYear) + String(date.month + 1) + String(date.date);
			file.addEventListener(Event.SELECT, onSaveSelect);
			if(png)
				file.save( PNGEncoder.encode( bd ) , Read.Name + str + ".png");
			else{
				var jpg:JPGEncoder = new JPGEncoder(90);
				file.save( jpg.encode( bd ), Read.Name + str + ".jpg");
			}
		}
		private function onSaveSelect(e:Event):void{
			file.removeEventListener(Event.SELECT, onSaveSelect);
		}
//  -->
//  <!-- Load pbj File function's
		private function onLoad_pbj():void{
			file = new FileReference();
			file.addEventListener(Event.SELECT, onSelect_pbj);
			file.browse( F_FILTER_PBJ );
		}
		
		private function onSelect_pbj(e:Event):void{
			file.removeEventListener(Event.SELECT, onSelect_pbj);
			file.addEventListener(Event.COMPLETE, onComp_pbj );
			file.load();
		}
		
		private function onComp_pbj(e:Event):void{
			var r:Read = new Read( file.data );
			s = Read.shader;
			d = s.data;
			bd = new BitmapData(240,240)
			sj = new ShaderJob( s, bd, 240, 240 );
			
			if(res){
				this.removeChild( res );
				res = null;
			}
			res = new ImgViewer( bd );
			this.addChild( res );
			res.x = w - 260; res.y = h - 275;
			
			file.removeEventListener(Event.COMPLETE, onComp_pbj );
			if(!first_load_flg){
				first_load_flg = true;
				menu.addSeparator( 0x0066CC, "|");
				menu.addMenuItem("view", "View Data");
				menu.addMenuItem("export", "Export");
				menu.addSeparator( 0x0066CC, "|");
				menu.addSeparator( 0x0066CC, "|");
				menu.addSeparator( 0xCC6600, "Save Image");
				menu.addMenuItem("savePng", "png");
				menu.addMenuItem("saveJpg", "jpg");
				menu.addSeparator( 0x0066CC, "|");
			}
			
			iniLab();
		}
//  Load pbj File function's-->

//  <!-- PBJ Viewer
		private function openView():void{
			if(view_flg){
				this.removeChild( viewer);
				viewer = null;
				view_flg = false;
				return;
			}
			if(viewer){
				this.removeChild( viewer);
				viewer = null;
			}
			var str:String = Read.meta_html + Read.inputs_html + Read.params_html;
			viewer = new PBJViewer(str, w - 40 , h - menu.height - 30 );
			viewer.x = (w - viewer.width ) >> 1;
			viewer.y = (h - viewer.height + menu.height) >>1;
			this.addChild( viewer );
			view_flg = true;
			exp_flg = false;
		}
//  PBJViewer-->
//  <!-- PBJ Export
		private function openExport():void{
			if(exp_flg){
				this.removeChild( viewer);
				viewer = null;
				exp_flg = false;
				return;
			}
			if(viewer){
				this.removeChild( viewer);
				viewer = null;
			}
			var str:String = Export.conv( Read.Name, Read.byte);
			viewer = new PBJViewer(str, w - 40 , h - menu.height - 30 );
			viewer.x = (w - viewer.width ) >> 1;
			viewer.y = (h - viewer.height + menu.height) >>1;
			this.addChild( viewer );
			view_flg = false;
			exp_flg = true;
		}
//  PBJ Export-->
		
	/////////////////////////////////////////////////////////////////
	}
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shader;
import flash.display.ShaderData;
import flash.display.ShaderInput;
import flash.display.ShaderParameter;
import flash.display.ShaderParameterType;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.ByteArray;
import mx.utils.Base64Encoder;
import __AS3__.vec.Vector;
import mx.controls.sliderClasses.Slider;
import mx.events.IndexChangedEvent;
import flash.events.KeyboardEvent;

/*
 *		Slider Container
 */
class SliderContainer extends Sprite{
	public function SliderContainer( num:int , values:Vector.<Object>, change:Function, sd:ShaderData,  integer:Boolean = false){
		var _name:String;
		var max:Array;
		var min:Array;
		var def:Array;
		var sub:String;
		var i:int=0;
		var len:int=0;
		if(values){
			var _len:int = values.length;
			var n:int = 0;
			for(var _i:int = 0; _i<_len; _i++){
				__setData(values[_i].type, values[_i].value);
			}
			function __setData( __v:String = "", str:String = ""):void{
				if( __v == "name") _name = values[i].value;
				else if( __v == "maxValue"){
						max = [];
						sub = "";
						n=0;
						if(str){
							max[n] = new String();
							for(i=0,len = str.length; i<len; i++){
								sub = str.substr(i,1);
								if(sub == ","){
									n++;
									max[n] = new String();
								}else
									max[n]+=sub;
							}
						}
				}else if( __v == "minValue"){
					min = [];
					sub = "";
					n=0;
					if(str){
						min[n] = new String();
						for(i=0,len = str.length; i<len; i++){
							sub = str.substr(i,1);
							if(sub == ","){
								n++;
								min[n] = new String();
							}else
								min[n]+=sub;
						}
					}
				}else if( __v == "defaultValue"){
					def = [];
					sub = "";
					n=0;
					if(str){
						def[n] = new String();
						for(i=0,len = str.length; i<len; i++){
							sub = str.substr(i,1);
							if(sub == ","){
								n++;
								def[n] = new String();
							}else
								def[n]+=sub;
						}
					}
				}
			}
			for(i = 0; i<num; i++){
				var xedit:Boolean = false;
				var nedit:Boolean = false;
				var mx:Number, mn:Number, df:Number;
				if(max) mx = Number( max[i] );
				else{ mx = 1; xedit = true;}
				if(min) mn = Number( min[i] );
				else{ mn= 0; nedit = true;}
				if(def) df = Number( def[i] );
				else df = 0;
				if(sd[_name].value) df = sd[_name].value[i];
				var s:Slider = new Slider( _name, i, mx, mn, df, 340, change, xedit, nedit, integer ); 
				this.addChild( s );
				s.x = 5;
				s.y = i * 55 + 14;
			}
			var g:Graphics = this.graphics;
			g.lineStyle(2, 0x444444);
			g.beginFill( 0x111111 );
			g.drawRoundRect( 0, 0 , 350, num * 55 + 20, 8, 8 );
			g.endFill();
		}
	}
}

/*
*		Slider
*/
class Slider extends Sprite{
	private var _name:String;
	private var _max:Number, _min:Number, _def:Number;
	private var now:Number;
	private var v:Number;
	private var _v:Number;
	private var flg:Boolean;
	private var pick:Sprite;
	private var maxT:TextField;
	private var minT:TextField;
	private var nowT:TextField;
	private var btn:SliderBtn;
	private var left:int, right:int, side:int;
	
	private var s_change:Function;
	private var num:int;
	private var f_int:Boolean;
	
	public function Slider( name:String, num:int,  max:Number, min:Number, def:Number, w:int , change:Function,xedit:Boolean = false, nedit:Boolean = false, integer:Boolean = false){
		_max = max;
		_min = min;
		_def = def;
		_name = name;
		this.num = num;
		f_int = integer;
		s_change = change;
		
		var g:Graphics = this.graphics;
		g.lineStyle(1, 0x999999);
		g.drawRect(0,0, w, 50);
		
		minT = textBox(min.toString(), 40, 18, nedit);
		//if(nedit)
		this.addChild( minT );
		minT.x = 5;
		maxT = textBox(max.toString(), 40, 18, xedit);
		this.addChild( maxT );
		maxT.x = w - (40 + 5);
		
		nowT = textBox(def.toString(), 80, 18, true);
		this.addChild( nowT );
		nowT.x =( w - (40 + 5)) >> 1;
		nowT.addEventListener(KeyboardEvent.KEY_DOWN, changeNow);
		
		maxT.y = minT.y = nowT.y = 5;
		
		g.moveTo( 5, 29);
		g.lineTo( 5, 45);
		var _a:Number = w-5;
		g.moveTo( _a, 29);
		g.lineTo( _a, 45);
		
		g.moveTo( 5, 37);
		g.lineTo(_a, 37);
		g.lineStyle(1, 0x00CCFF);
		_a = w>>1;
		g.moveTo( _a, 34);
		g.lineTo( _a, 40);
		
		left = 5;
		right = w - 5;
		side = right - left;
		
		var n1:Number = 0;
		var n2:Number = 0;
		if(max<0) n1 = -max;
		else n1 = max;
		if(min<0) n2= -min;
		else n2= min;
		v = (n1+n2);
		_v = side * n2/v;
		
		btn = new SliderBtn(8, 14, 0xCCCCCC, 0xCC6600);
		this.addChild( btn );
		btn.y = 37;
		
		btn.x = side * (def/v) + _v +left; // やけに難しかった…
		
		btn.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void{
			btn.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
			btn.stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
		});
	}
	
	private function onMove(e:MouseEvent):void{
		btn.x = mouseX;
		if(btn.x < left) btn.x = left;
		else if(btn.x > right) btn.x = right;
		
		now = (btn.x - left - _v) / side * v; // やけに難しかった…
		if(f_int) now = Math.round( now );
		
		nowT.text = now.toString();
		
		s_change( _name, num.toString(), now );
	}
	
	private function onUp(e:MouseEvent):void{
		btn.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
		btn.stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
	}
	
	private function textBox( txt:String, w:int, h:int, edit:Boolean):TextField{
		var t:TextField = new TextField();
		t.width = w;
		t.height = h;
		t.text = txt;
		if(!edit){
			t.border = true;
			t.textColor = t.borderColor = 0xCCCCCC;
			t.thickness = 1;
		}else{
			t.background = t.border =  true;
			t.backgroundColor = 0xCCCCCC;
			t.thickness = 1;
			t.borderColor = 0xFFFFFF;
			t.mouseEnabled = t.selectable = true;
			t.type = "input";
		}
		return t;
	}
	
	private function changeMax(e:KeyboardEvent):void{
		if(e.keyCode == 13){
			var n1:Number = Number(maxT.text);
			var n2:Number = _min;
			if(n1<0) n1 = -n1;
			else n1 = n1;
			if(n2<0) n2= -n2;
			else n2= n2;
			v = (n1+n2);
			_v = side * n2/v;
			
			now = Number(nowT.text);
			if(f_int) now = Math.round( now );
			btn.x = side * (now/v) + _v +left; 
			s_change( _name, num.toString(), now );
		}
	}
	
	private function changeMin(e:KeyboardEvent):void{
		if(e.keyCode == 13){
			var n1:Number = _max;
			var n2:Number = Number(minT.text);
			if(n1<0) n1 = -n1;
			else n1 = n1;
			if(n2<0) n2= -n2;
			else n2= n2;
			v = (n1+n2);
			_v = side * n2/v;
			
			now = Number(nowT.text);
			if(f_int) now = Math.round( now );
			btn.x = side * (now/v) + _v +left; 
			s_change( _name, num.toString(), now );
		}
	}
	
	private function changeNow(e:KeyboardEvent):void{
		if(e.keyCode == 13){
			now = Number(nowT.text);
			if(f_int) now = Math.round( now );
			btn.x = side * (now/v) + _v +left; 
			s_change( _name, num.toString(), now );
		}
	}
	
	public function get value():Number{
		if(!flg) return v;
		else return Math.round( v );
	}
}
/*
*		SliderBtn
*		Sliderのつまみ
*/
class SliderBtn extends Sprite{
	private var g:Graphics;
	private var color:uint;
	private var over:uint;
	private var w:int, h:int;
	
	public function SliderBtn(_w:int, _h:int , _color:uint, overColor:uint){
		w = _w >>1;
		h = _h >>1;
		color = _color;
		over = overColor;
		
		g = this.graphics;
		draw(color);
		this.addEventListener(Event.ADDED,function(e:Event):void{
			add();
		});
	}
	
	private function add():void{
		this.addEventListener(MouseEvent.ROLL_OVER, function(e:MouseEvent):void{
			draw(over);
		});
		this.addEventListener(MouseEvent.ROLL_OUT, function(e:MouseEvent):void{
			draw(color);
		});
	}
	
	private function draw(c:uint):void{
		g.clear();
		g.lineStyle(1, c );
		g.drawRect(-w,-h,w*2, h*2);
		g.lineStyle( undefined );
		g.beginFill( c );
		g.moveTo(-w,-h);
		g.lineTo( w, -h);
		g.lineTo(-w,h);
		g.lineTo(w,h);
		g.lineTo(-w,-h);
		g.endFill();
	}
}


/*
*		ImgViewer
*		ShderJobの結果物を表示
*/
class ImgViewer extends Sprite{
	private var bmp:Bitmap;
	
	public function ImgViewer( bd:BitmapData ){
		bmp = new Bitmap( bd );
		this.addChild( bmp );
		var g:Graphics = this.graphics;
		g.lineStyle( 0 );
		g.beginFill( 0x111111 );
		g.drawRect( 0, 0, 250, 260 );
		g.endFill();
		bmp.x = 5;
		bmp.y = 15;
	}
	
	public function upDate( bd:BitmapData ):void{
		bmp.bitmapData = bd;
	}
}

/*
*		PBJViewer
*		Shderのパラメータ・Exportの文字列表示用
*/
class PBJViewer extends Sprite{
	private var w:int, h:int;
	
	public function PBJViewer( txt:String , _w:int, _h:int){
		w = _w; h = _h;
		var g:Graphics = this.graphics;
		g.lineStyle(2);
		g.beginFill( 0x111111 );
		g.drawRoundRect( 0, 0, w, h, 5, 5);
		g.endFill();
		var tf:TextField = new TextField();
		tf.background = true;
		tf.backgroundColor = 0xCCCCCC;
		tf.width = w - 50;
		tf.height = h - 50;
		this.addChild( tf );
		
		tf.tabEnabled = true;
		tf.wordWrap = false;
		tf.scrollV = 100;
		tf.htmlText = txt;
		tf.x =  (w - tf.width) >> 1;
		tf.y = (h - tf.height) >> 1;
	}
}


/*
*		今アプリにて絶賛使用のメニュークラス
*		Spriteでボタンを作るのがめんどくさかったので。
*/
class MyMenu extends TextField{
	private var str:String = "    ";
	
	public function MyMenu( bg:uint, color:uint ){
		this.autoSize = "left";
		this.background = true;
		this.backgroundColor = bg;
		this.textColor = color;
	}
	
	public function addSeparator( color:uint, code:String ):void{
		str +=  "<font color=\"#" + color.toString(16) + "\">" + code + "</font>    ";
		htmlText = str;
	}
	
	public function addMenuItem( eventText:String, txt:String, coloring:Boolean = true, color:uint = 0xCCCCCC ):void{
		if(coloring) str += setColor(color, setLink(eventText, txt) ) + "    ";
		else str += setLink(eventText, txt) + "    ";
		htmlText = str;
	}
	
	private function setLink(eventText:String, txt:String):String{
		return "<u><a href=\"event:" + eventText + "\">" + txt + "</a></u>";
	}
	
	private function setColor(color:uint, txt:String):String{
		return "<font color=\"#" + color.toString(16) + "\">" + txt + "</font>";
	}
}

/*
*		Export
*		BASE64形式でwonderflで使いやすい感じで出力
*/
class Export{
	public static function conv( name:String, data:ByteArray ):String{
		var br:String = "\n";
		var tab:String = "\t";
		var tab2:String = "\t\t";
		var tab3:String = tab + tab2;
		
        var enc:Base64Encoder = new Base64Encoder();
        enc.encodeBytes( data );
        var str2:String = "";
        var b64:String = enc.toString();
        var len:uint = b64.length;
        for (var i:uint = 0; i < len; i++){
            var sub:String = b64.substr(i, 1);
            if (sub == "\n")
                continue;
            str2 += sub;
        }
        return "" +
"class " + name + " extends Shader" + br +
"{" + br +
tab + "public function " + name+ "()" + br +
tab + "{" + br +
tab2 +"var dec:Base64Decoder = new Base64Decoder();" + br +
tab2 +"dec.decode( \"" + str2+ "\" );" + br +
tab2 +"this.byteCode = dec.toByteArray();" + br +
tab2 +"dec = null;" + br + 
tab + "}"+ br +
"}" + br + br + br +
"/*高機能なExport機能は\n↓にて配布中の pbjExplorer をお使いください。" + br +
"http://zahir.s69.coreserver.jp/air/pbjexplorer/pbjExplorer.air" + br +
"要 Adobe AIR1.5以上*/";
	}
}


/*
*		Read
*		Shderの各種パラメータを読むクラス
*		色々ややこしい
*/
class Read{
	private static var s:Shader;
	
	private static var inputs:Array = [];
	private static var params:Array = [];
	private static var meta:Array = [];
	
	private const br:String = "\n";    
    private const sFont:String = "<font color=\"#";
    private const _sFont:String = "\">";
    private const eFont:String = "</font>";
    private static const tab:String = "\t";
    private static const tab2:String = "\t\t";
    private static const tab3:String = "\t\t\t";
    private static const tab4:String = "\t\t\t\t";
    
    private const Name:uint = 0x0000FF;
    private const Type:uint = 0x339900;
    private const Menbers:uint = 0xFF6600;
    
    private static var p_name:String;
    private static var input_txt:String;
    private static var params_txt:String;
    private static var meta_txt:String;
    
    private static var code:ByteArray;
    
    public static function get shader():Shader{ return s;}
	public static function get meta_data():Array{ return meta }
	public static function get inputs_data():Array{ return inputs; }
	public static function get params_data():Array{ return params; }
	public static function get meta_html():String{ return meta_txt; }
	public static function get inputs_html():String{ return input_txt; }
	public static function get params_html():String{ return params_txt; }
	public static function get Name():String{ return p_name; }
	public static function get byte():ByteArray{ return code; }
	
	public function Read( data:ByteArray ){
		code = data;
		s = new Shader( data );
		inputs = [];
		params = [];
		meta = [];
		
		for (var p:String in s.data) {
            if(s.data[p] is ShaderParameter){
                var o:Vector.<Object> = new Vector.<Object>();
                for (var d:String in s.data[p]) 
                    o.push({"type":d, "value":s.data[p][d] });
                params.push({ "name": p, "type":s.data[p].type, "values": sortParamValues( o ) });
            }else if(s.data[p] is ShaderInput == false && s.data[p] is ShaderParameter == false){
                meta.push({ "name":p, "value":s.data[p] });
            }else{
                inputs.push({ "name":p, "channels":s.data[p].channels });
            }
        }
        params.sortOn( "name", Array.CASEINSENSITIVE );
        inputs.sortOn("name", Array.CASEINSENSITIVE );
        
        input_txt = getInputsHTML( inputs );
        params_txt = getParamsHTML( params );
        meta_txt = getMetaData();
	}
	
	private function sortParamValues( vec:Vector.<Object> ):Vector.<Object>{
        var len:int = vec.length;
        var _name:Object;
        var _description:Object;
        var _maxValue:Object;
        var _minValue:Object;
        var _defaultValue:Object;
        for(var i:int = 0; i<len; i++){
            if(vec[i].type == "name") _name = vec[i]; 
            else if(vec[i].type == "description") _description = vec[i];
            else if(vec[i].type == "maxValue") _maxValue = vec[i];
            else if(vec[i].type == "minValue") _minValue = vec[i];
            else if(vec[i].type == "defaultValue") _defaultValue = vec[i];
        }
        vec = new Vector.<Object>();
        if(_name) vec.push(_name);
        if(_description) vec.push(_description);
        if(_maxValue) vec.push(_maxValue);
        if(_minValue) vec.push(_minValue);
        if(_defaultValue) vec.push(_defaultValue);
        return vec;
    }
	 
	private  function getMetaData():String{
        var str:String = "";
        var _name:String;
        var _nameSpace:String;
        var _vendor:String;
        var _version:String;
        var _description:String;
        
        var len:int = meta.length;
        for(var i:int = 0; i<len; i++){
            if(meta[i].name == "name"){ _name = "<b>" + meta[i].name + "</b> : " + meta[i].value + "\n"; p_name = meta[i].value;}
            else if(meta[i].name == "namespace") _nameSpace = "<b>" + meta[i].name + "</b> : " + meta[i].value + "\n";
            else if(meta[i].name == "vendor") _vendor = "<b>" + meta[i].name + "</b> : " + meta[i].value + "\n";
            else if(meta[i].name == "version") _version = "<b>" + meta[i].name + "</b> : " + meta[i].value + "\n";
            else if(meta[i].name == "description") _description = "<b>" + meta[i].name + "</b> : " + meta[i].value + "\n";
        }
        if(_name) str += _name;
        if(_nameSpace) str += _nameSpace;
        if(_vendor) str +=_vendor;
        if(_version) str += _version;
        if(_description ) str += _description;
        str += br+br;
        return str;
    }
    
    private function getInputsHTML( _arr:Array ):String{
        var str:String = sFont + (0x339900).toString(16) + _sFont;
        str += "/////////////////////////////////" + br;
        str += "//  Input's  ////////////////////" + br ;
        str += "/////////////////////////////////" + eFont + br + br;
        var len:int = _arr.length;
        for(var i:int = 0; i<len; i++){
            str += sFont + Name.toString(16) + _sFont + _arr[i].name + eFont;
            str +=  " ( " + sFont + Type.toString(16) + _sFont + _arr[i].channels + eFont + " ) " + br;
        }
        str += br + br;
        return str;
    }
    
    private function getParamsHTML( _arr:Array ):String{
        var str:String = sFont + (0x339900).toString(16) + _sFont;
        str += "/////////////////////////////////" + br;
        str += "//  Parameter's  //////////////" + br;
        str += "/////////////////////////////////" + eFont + br + br;
        var len:int = _arr.length;
        for(var i:int = 0; i<len; i++){
            var lv:Vector.<Object> = _arr[i].values as Vector.<Object>;
            str += sFont + Name.toString(16) + _sFont + _arr[i].name + eFont;
            str +=  " ( " + sFont + Type.toString(16) + _sFont + _arr[i].type + eFont + " ) " + br;
            str += "<" + br;
            if(lv){
                var l:int = lv.length;
                for(var j:int=0; j<l; j++){
                    str += "\t\t" + sFont + Menbers.toString(16) + _sFont + lv[j].type + eFont + " : " + lv[j].value + br; 
                }
                str += ">;" + br + br;
            }
        }
        return str;
    }
}