1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  
     5  import org.aswing.utils.MathUtils;
     6  import org.aswing.utils.MCUtils;
     7  
     8  /**
     9   * The creater use to create UI elements like movieclips, textfield...
    10   * @author iiley
    11   */
    12  class org.aswing.ElementCreater{
    13  	
    14  	private static var _instance:ElementCreater;
    15  	private var _prefix:String="aswing_e_";
    16  	private var _nextHandle:Number=0;
    17  	
    18  	private var _defaultMovieClip:Object={tabEnabled:false, _focusrect:false, useHandCursor:false};
    19  	private var _defaultTextField:Object={tabEnabled:false, autoSize:"center", embedFonts:false, selectable:false, textColor:0xB333C};	
    20  	
    21  	private function ElementCreater(){};
    22  	
    23  	public static function getInstance():ElementCreater{
    24  		if(_instance==undefined){
    25  			_instance=new ElementCreater();
    26  		}
    27  		return _instance;
    28  	}
    29  	
    30  	/**
    31  	 * Creates and returns a new empty MovieClip.
    32  	 * <p>
    33  	 * createMC(position_mc:MovieClip, nameStart:String, depth:Number)<br>
    34  	 * createMC(position_mc:MovieClip, nameStart:String,)<br>
    35  	 * createMC(position_mc:MovieClip)<br>
    36  	 * 
    37  	 * @param position_mc new mc's parent.
    38  	 * @param nameStart the new mc's name prefix. Default is aswing_e_
    39  	 * @param depth new mc's depth. Default is getNextHighestDepth
    40  	 * @return the new empty MC created.
    41  	 */
    42  	public function createMC(position_mc:MovieClip, nameStart:String, depth:Number):MovieClip{
    43  		return createMCWithName(position_mc, getAvailableName(position_mc, nameStart), depth);
    44  	}
    45  	
    46  	/**
    47  	 * Creates and returns a new empty MovieClip with specified name.
    48  	 * <p>
    49  	 * createMCWithName(position_mc:MovieClip, name:String, depth:Number)<br>
    50  	 * createMCWithName(position_mc:MovieClip, name:String,)<br>
    51  	 * 
    52  	 * @param position_mc new mc's parent.
    53  	 * @param name the new mc's name.
    54  	 * @param depth new mc's depth. Default is getNextHighestDepth
    55  	 * @return the new empty MC created.
    56  	 */	
    57  	public function createMCWithName(position_mc:MovieClip, name:String, depth:Number):MovieClip{
    58  		if(depth == undefined) depth = position_mc.getNextHighestDepth();
    59  		var result_mc:MovieClip = position_mc.createEmptyMovieClip(name, depth);
    60  		initObjectParams(result_mc, _defaultMovieClip);
    61  		return result_mc;
    62  	}
    63  	
    64  	/**
    65  	 * Attaches and returns a new MovieClip by given linkage id.
    66  	 * <p>
    67  	 * attachMC(position_mc:MovieClip, linkage:String, nameStart:String, depth:Number)<br>
    68  	 * attachMC(position_mc:MovieClip, linkage:String, nameStart:String,)<br>
    69  	 * attachMC(position_mc:MovieClip, linkage:String,)<br>
    70  	 * 
    71  	 * @param position_mc new mc's parent.
    72  	 * @param linkage the linkage id.
    73  	 * @param nameStart the new mc's name prefix. Default is aswing_e_
    74  	 * @param depth new mc's depth. Default is getNextHighestDepth
    75  	 * @return the new MC attached.
    76  	 */	
    77  	public function attachMC(position_mc:MovieClip, linkage:String, nameStart:String, depth:Number):MovieClip{
    78  		return attachMCWithName(position_mc, linkage, getAvailableName(position_mc, nameStart), depth);
    79  	}
    80  	
    81  	/**
    82  	 * Attaches and returns a new MovieClip by given linkage id and specified name.
    83  	 * <p>
    84  	 * attachMCWithName(position_mc:MovieClip, linkage:String, name:String, depth:Number)<br>
    85  	 * attachMCWithName(position_mc:MovieClip, linkage:String, name:String,)<br>
    86  	 * 
    87  	 * @param position_mc new mc's parent.
    88  	 * @param linkage the linkage id.
    89  	 * @param name the new mc's name.
    90  	 * @param depth new mc's depth. Default is getNextHighestDepth
    91  	 * @return the new MC attached.
    92  	 */		
    93  	public function attachMCWithName(position_mc:MovieClip, linkage:String, name:String, depth:Number):MovieClip{
    94  		if(depth == undefined) depth = position_mc.getNextHighestDepth();
    95  		var result_mc:MovieClip = position_mc.attachMovie(linkage, name, depth);
    96  		initObjectParams(result_mc, _defaultMovieClip);
    97  		return result_mc;
    98  	}	
    99  	
   100  	/**
   101  	 * Creates and returns a new TextField.
   102  	 * <p>
   103  	 * createTF(position_mc:MovieClip, nameStart:String, depth:Number)<br>
   104  	 * createTF(position_mc:MovieClip, nameStart:String,)<br>
   105  	 * createTF(position_mc:MovieClip)<br>
   106  	 * 
   107  	 * @param position_mc new textField's parent.
   108  	 * @param nameStart the new textField's name prefix. Default is aswing_e_
   109  	 * @param depth new textField's depth. Default is getNextHighestDepth
   110  	 * @return the new textField created.
   111  	 */	
   112  	public function createTF(position_mc:MovieClip, nameStart:String, depth:Number):TextField{
   113  		return createTFWithName(position_mc, getAvailableName(position_mc, nameStart), depth);
   114  	}
   115  	
   116  	/**
   117  	 * Creates and returns a new TextField with specified name.
   118  	 * <p>
   119  	 * createTF(position_mc:MovieClip, name:String, depth:Number)<br>
   120  	 * createTF(position_mc:MovieClip, name:String,)<br>
   121  	 * 
   122  	 * @param position_mc new textField's parent.
   123  	 * @param name the new textField's name.
   124  	 * @param depth new textField's depth. Default is getNextHighestDepth
   125  	 * @return the new textField created.
   126  	 */		
   127  	public function createTFWithName(position_mc:MovieClip, name:String, depth:Number):TextField{
   128  		if(depth == undefined) depth = position_mc.getNextHighestDepth();
   129  		position_mc.createTextField(name, depth,0,0,0,0);
   130  		var result_txt:TextField = position_mc[name];
   131  		initObjectParams(result_txt, _defaultTextField);
   132  		return result_txt;
   133  	}
   134  	
   135  	private function getAvailableName(position_mc:MovieClip, nameStart:String):String{
   136  		if(nameStart == undefined) nameStart = _prefix;
   137  		while(_nextHandle < MathUtils.STRING_REPRESENTABLE_MAX){
   138  			var name:String = nameStart + (_nextHandle++);
   139  			if(!MCUtils.isMovieClipExist(position_mc[name])){
   140  				return name;
   141  			}
   142  		}
   143  		_nextHandle = -1;
   144  		while(_nextHandle > MathUtils.STRING_REPRESENTABLE_MIN){
   145  			var name:String = nameStart + (_nextHandle--);
   146  			if(!MCUtils.isMovieClipExist(position_mc[name])){
   147  				return name;
   148  			}
   149  		}
   150  		//this should be never happen, since no one can use whole numbers for MCs 
   151  		//between MathUtils.STRING_REPRESENTABLE_MIN to MathUtils.STRING_REPRESENTABLE_MAX
   152  		trace("there_is_not_any_number_available_for_naming");
   153  		return nameStart + "_there_is_not_any_number_available_for_naming";
   154  	}
   155  	
   156  	private function initObjectParams(target_obj:Object, params_obj:Object):Void{
   157  		if(params_obj == undefined) return;
   158  		for(var i:String in params_obj){
   159  			target_obj[i] = params_obj[i];
   160  		}
   161  	}
   162  }
   163