 	case AutoGlowHeight				( Bool )
 	case Font						( UIFont )
 	case TagBackgroundColor			( UIColor )
+	case TagSelectedColor			( UIColor )
 	case TagTextColor				( UIColor )
 	case TagPrefix					( String )
+	case TagMaxCharactors			( Int )
 	case AddButtonBackgroundColor	( UIColor )
 	case AddButtonTextColor			( UIColor )
 	case EnableEdit					( Bool )
+	case MaxTagCount				( Int )
 }
 
 // ------------------------------------------------------------------------------------------------
 @objc public protocol TagViewDelegate
 {
-	optional func onDidEndEditing( sender: UIView )
+	@objc optional func onChangedLayoutTag( sender: UIView )
+	@objc optional func onDidEndEditingTag( sender: UIView )
+	@objc optional func onTapTag( name: String, userData: Any? )
 }
 
 // ------------------------------------------------------------------------------------------------
 class TagView: UIView, UITextFieldDelegate
 {
 	var _scrollView					: UIScrollView!
-	var _tagIndex					: Int		= 0
+	var _tagIndex					: Int				  = 0
+	var _touchTagIndex				: Int				  = -1
 	var _tagFields					: [Int: UITextField]! = [:]
-	var _tagFieldMaxX				: CGFloat	= 0.0
-	var _tagFieldMinY				: CGFloat	= 0.0
+	var _userDatum					: [Int: Any]!		  = [:]
+	var _tagFieldMaxX				: CGFloat			  = 0.0
+	var _tagFieldMinY				: CGFloat			  = 0.0
 	var _basePosition				: CGPoint!
 	var _baseSize					: CGSize!
 	var _addButton					: UIButton!
-	var _outerMergine				: CGFloat	= 5.0
-	var _innerMergine				: CGFloat	= 2.5
-	var _autoGlowHeight				: Bool		= true
+	var _outerMergine				: CGFloat			  = 5.0
+	var _innerMergine				: CGFloat			  = 2.5
+	var _autoGlowHeight				: Bool				  = true
 	var _font						: UIFont!
-	var _tagBackgroundColor			: UIColor	= UIColor.whiteColor()
-	var _tagTextColor				: UIColor	= UIColor.blackColor()
-	var _tagPrefix					: String	= "#"
-	var _addButtonBackgroundColor	: UIColor	= UIColor.whiteColor()
-	var _ddButtonTextColor			: UIColor	= UIColor.blackColor()
-	var _enableEdit					: Bool		= true
+	var _tagBackgroundColor			: UIColor			  = UIColor.white
+	var _tagSelectedColor			: UIColor			  = UIColor.white
+	var _tagTextColor				: UIColor			  = UIColor.black
+	var _tagPrefix					: String			  = "#"
+	var _tagMaxCharactors			: Int				  = 30
+	var _tagCharCountLabel			: UILabel!
+	var _addButtonBackgroundColor	: UIColor			  = UIColor.white
+	var _addButtonTextColor			: UIColor			  = UIColor.black
+	var _enableEdit					: Bool				  = true
+	var _maxTagCount				: Int				  = 1000
+	var _tagCount					: Int				  = 0
+	var _targetTextField			: UITextField!
 	weak var delegate				: TagViewDelegate?
 
 	// --------------------------------------------------------------------------------------------

		_tagFieldMaxX = 0.0
		_tagFieldMinY = _outerMergine
		var tagFieldMaxY = CGFloat( 0.0 )
		for ( _, value ) in _tagFields.sort( { $0.0 < $1.0 } )
		{
			value.frame = CGRectMake( _tagFieldMaxX + _outerMergine, _tagFieldMinY, value.frame.width, value.frame.height )
			if frame.width - _outerMergine * 2 < value.frame.width
			{
				value.frame = CGRectMake( _outerMergine, value.frame.maxY + _outerMergine, frame.width - _outerMergine * 2, value.frame.height )
			}
			else if frame.width - _outerMergine < value.frame.maxX
			{

	// --------------------------------------------------------------------------------------------
	func onTapAddButton( sender: UIButton )
	{
		if 0 < _maxTagCount - _tagCount
		{
			addTag( tagString: _tagPrefix )
			_tagCount += 1
			_addButton.isHidden = ( _maxTagCount - _tagCount ) == 0
		}
	}
	// --------------------------------------------------------------------------------------------
	func textFieldShouldBeginEditing( _ textField: UITextField ) -> Bool
	{
		_targetTextField = textField
		updateCharactorCount()
		return true
	}
	// --------------------------------------------------------------------------------------------
	func textField( _ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String ) -> Bool
	{
		Timer.scheduledTimer( timeInterval: 0.05, target: self, selector: #selector( onTimerTextField ), userInfo: _tagFields[ textField.tag ]!, repeats: false )
		return true
	}
	// --------------------------------------------------------------------------------------------
	func onTimerTextField( timer: Timer )
	{
		if _tagMaxCharactors < _targetTextField.text!.characters.count
		{
			_targetTextField.text = ( _targetTextField.text! as NSString ).substring( to: _tagMaxCharactors )
		}
		updateCharactorCount()
		fitTag( tagField: timer.userInfo as! UITextField )
		updateLayout()
	}
	// --------------------------------------------------------------------------------------------
	func textFieldDidEndEditing( _ textField: UITextField )
	{
		if textField.text == "" || textField.text == _tagPrefix
		{
			removeTag( tagField: _tagFields[ textField.tag ]! )
			_tagCount -= 1
			_addButton.isHidden = ( _maxTagCount - _tagCount ) == 0
		}
		else
		{
			fitTag( tagField: _tagFields[ textField.tag ]! )
		}
		updateLayout()
	}
	// --------------------------------------------------------------------------------------------
	func textFieldShouldReturn( _ textField: UITextField ) -> Bool
	{
		textField.resignFirstResponder()
		hideCharactorCount()
		endEditing( true )
		delegate?.onDidEndEditingTag!( sender: self )
		return true
	}
	// --------------------------------------------------------------------------------------------
	func onTapBackground( sender: UITapGestureRecognizer )
	{
		let point = sender.location( in: self )
		for index in 0 ..< _tagFields.count
		{
			if _tagFields[ index ]?.frame.contains( point ) == true
			{
				_tagFields[ index ]!.backgroundColor = _tagSelectedColor
				Timer.scheduledTimer( timeInterval: 0.05, target: self, selector: #selector( self.onTouchEnd ), userInfo: index, repeats: false )
				_touchTagIndex = index
				return
			}
		}
	}
	// --------------------------------------------------------------------------------------------
	func onTouchEnd( timer: Timer )
	{
		_tagFields[ _touchTagIndex ]!.backgroundColor = _tagBackgroundColor
		delegate?.onTapTag!( name: ( _tagFields[ _touchTagIndex ]?.text )!, userData: _userDatum[ _touchTagIndex ] )
	}
}
