//bkplus 透明背景贴图
import win.ui;
import gdip.graphics;
import gdip.bitmap;
import gdip.solidBrush;
import gdip.lineBrush;
import gdip.pathGradientBrush;
import gdip.path;
import gdip.stringformat;
import util.metaProperty;

namespace win.ui.ctrl;
class bkplus{
	ctor(parent,tParam){ 
		
		this.text = tParam.text;
		if(tParam.bgcolor){
			this.backgroundColor = ..gdi.rgbReverse(tParam.bgcolor) | 0xFF000000;
		}
		if(tParam.forecolor){
			this.foregroundColor = ..gdi.rgbReverse(tParam.forecolor) | 0xFF000000;
		}
		
		this.paddingRight = tParam.paddingRight:0;
		this.paddingBottom = tParam.paddingBottom:0;
		this.paddingLeft = tParam.paddingLeft:0;
		this.paddingTop = tParam.paddingTop:0;
		if(!#tParam.repeat) tParam.repeat = "expand";
		
		this.onlyDirectDrawBackground = true;//禁止创建窗口
		this.rect = ::RECT();
		
		if(!_WINXP) {
			if( !tParam.font ) tParam.font = ::LOGFONT(name="Segoe UI");
			elseif( tParam.font.name=="Tahoma" )  tParam.font.name="Segoe UI";
		}
		else {
			if( !tParam.font ) tParam.font = ::LOGFONT(name="MS Shell Dlg");
			elseif( tParam.font.name=="Tahoma" )  tParam.font.name="MS Shell Dlg";
		}
		
		if(tParam.font.name!="Segoe UI"){
			this.textRenderingHint =  3/*_GdipTextRenderingHintAntiAliasGridFit*/;
		}
		else {
			this.textRenderingHint = 5/*_TextRenderingHintClearTypeGridFit*/;
		}
		
		this.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/;
		this.interpolationMode = 7/*_InterpolationModeHighQualityBicubic*/;
	};
	onDirectDrawBackground = function(hdc,graphics){
		var rc = this.rect;
		if(!graphics) { graphics = ..gdip.graphics(hdc); hdc = null; }
		
		graphics.smoothingMode = this.smoothingMode;
		graphics.compositingQuality = 2/*_GdipCompositingQualityHighQuality*/;
		graphics.interpolationMode = this.interpolationMode;
		graphics.pixelOffsetMode = 2/*_PixelOffsetModeHighQuality*/
		graphics.textRenderingHint =  this.textRenderingHint;
		
		if(this.background){
			if(type(this.background) == "string"){
				this.background = ..gdip.loadCachedBitmap(this.background);
				if(!this.background ) return;
			}
			graphics.drawBackground(this.background,this.repeat,rc,this.bkTop:0,this.bkRight:0,this.bkBottom:0,this.bkLeft:0);
		}
		elseif( (this.backgroundColor!==null) && (this.linearGradient== null) ){
			var brush = ..gdip.solidBrush(this.backgroundColor);
			graphics.fillRectangle(brush,rc.xywh() );
			brush.delete()
		}
		
		var rcContent = rc.copy();
		rcContent.right = rcContent.right - this.paddingRight;
		rcContent.bottom = rcContent.bottom - this.paddingBottom;
		rcContent.left = rcContent.left + this.paddingLeft;
		rcContent.top = rcContent.top + this.paddingTop;
		
		if(this.foregroundColor!==null){
			if(this.linearGradient!== null && this.backgroundColor !== null ){
				if(this.linearGradient>=0){
					var rf = rc.float();
					rf.angle = this.linearGradient; 
					var brush = ..gdip.lineBrush(rf,this.backgroundColor,this.foregroundColor);
					graphics.fillRectangle( brush,rc.xywh());
					brush.delete();
				}
				else {
					var pathGradient = ..gdip.path();
					pathGradient.addEllipse(rc.left,rc.top,rc.width(),rc.height());
					
					var brush = ..gdip.pathGradientBrush(pathGradient);
					brush.setCenterColor(this.backgroundColor);
					brush.setSurroundColors(this.foregroundColor);
					brush.gammaCorrection = true;
					graphics.fillEllipse(brush,rc.xywh());
					brush.delete();	
					pathGradient.delete();
				}
			}
			else { 
				var brush = ..gdip.solidBrush(this.foregroundColor);
				graphics.fillRectangle(brush,rcContent.xywh() );
				
				brush.delete()	
			}
		}
		
		
		if(this.onDrawBackground){
			this.onDrawBackground(graphics,rc)
		}
		
		if(#this.text){
			var f = ..gdip.stringformat();  
			f.align = __stringAlignment[ this.align : "center" ] 
			f.lineAlign = __stringAlignment[ this.valign : "center" ] 
			f.hotkeyPrefix = 1/*_GdipHotkeyPrefixShow*/; 
			f.flags =  0x800/*_GdipStringFormatFlagsMeasureTrailingSpaces*/ |  0x1000/*_StringFormatFlagsNoWrap*/; 
			if(this.trimming!==null) f.trimming = this.trimming;
			
			if( !this.argbColor ) this.argbColor = ..gdi.rgbReverse( this.color!=-1? this.color : 0 ) | ( 0xFF << 24 );
			var brush = ..gdip.solidBrush( this.argbColor );
			var rectf = rcContent.float();
			if( this[["(font)"]] ) {
				if( !this.onDrawString ){
					graphics.drawString( this.text ,this[["(font)"]],rectf, f,brush);
				}
				else{
					this.onDrawString(graphics,this.text,this[["(font)"]],rcContent, f,brush)	
				}
			}
			brush.delete();
			f.delete();
		}
		
		if(!hdc) graphics.delete();
	};
	setPos = function(x,y,cx,cy){
		this.rect.ltrb(x,y,cx,cy);
	};
	getPos = function(){
		return this.rect.xywh();
	};
	redraw = function(){
		owner[["_parentForm"]].redrawBackground(owner.rect);
	}; 
	_onDestroy = function(){
		if(this.bitmap){
			::DeleteObject(this.bitmap);
			this.bitmap = null;
		}
	};
	@_metaProperty
}

bkplus._metaProperty = ..util.metaProperty(

	background = {
		_get = function () {
			return owner.getBackground();
		}
		_set = function (v) {
			var old = owner.setBackground(v,,!owner[["initializing"]]);
		}
	};
	setBackground = function(bmp,cacheName){
		var background = owner[["(background)"]];
		
		if(type(bmp)==type.number){
			owner[["(background)"]] = null;
			if( bmp == owner.backgroundColor ) return;
			owner.backgroundColor = bmp;
			return;
		}
		owner.backgroundColor = null;
		if( bmp == background ) return;
		
		var old = background;
		if( bmp ){
			background = ..gdip.loadCachedBitmap(bmp,cacheName); 
			if( background ){ 
				owner[["(background)"]] = background;
			} 
			else {
				return;
			} 
		}
		else {
			owner[["(background)"]] = null;
		}
		
		return old;  
	};
	getBackground = function(){
		return owner[["(background)"]];
	};
	foreground = {
		_get = function () {
			return owner.foregroundColor;
		}
		_set = function (v) {
			owner.foregroundColor = v;
		}
	};
	getFont = function(){
		if(owner["(font)"]){
			var graphics = ..gdip.graphics({hwnd=owner[["_parentForm"]].hwnd});
			var lf = owner["(font)"].getLogFont(graphics);
			graphics.delete();
			return lf;
		} 
	};
	setFont = function(f,own = true ){
		if( type(f) == type.pointer ){
			var lf = LOGFONT(); 
			if( !::GetObject(f, ..raw.sizeof(lf), lf) ) return;
			if(own) ::DeleteObject(f);
			f = lf;
		}
		if(type(f) != type.table ) error("参数错误@1",2)
		if(!f._struct) f = ::LOGFONT(f);
		if( f.handle && own) f.deleteIndirect();
		
		if(f.color) {
			owner.color = f.color
			owner.argbColor = ..gdi.rgbReverse( f.color ) | ( 0xFF << 24 ) 
		} 

		var hdc = ::GetDC(owner[["_parentForm"]].hwnd);
		owner[["(font)"]] = ..gdip.font( hdc,f ); 
		::ReleaseDC(owner[["_parentForm"]].hwnd,hdc);  

		return true; 
	};
	enableDpiScaling = function(scaleX,scaleY){
		if( scaleX === false ){  return; } 
		if(!( scaleX && scaleY ) ) { return; 	}  
		
		if( !owner[["dpiScaleX"]] ) {
			owner[["dpiScaleX"]] = 1;
			owner[["dpiScaleY"]] = 1;
		}
		var origScaleX,origScaleY = owner[["dpiScaleX"]],owner[["dpiScaleY"]];
		owner[["dpiScaleX"]] = scaleX;
		owner[["dpiScaleY"]] = scaleY;
		
		var font = owner.getFont();
		if( font ){
			font.h = ( font.h / origScaleY ) * scaleY;
			owner.setFont(font);
		}
	};
)

bkplus.__stringAlignment = { 
		top =0/*_GdipStringAlignmentNear*/ ;bottom = 2/*_GdipStringAlignmentFar*/ ;
		left =0/*_GdipStringAlignmentNear*/ ; right = 2/*_GdipStringAlignmentFar*/;
		center = 1/*_GdipStringAlignmentCenter*/;
	}	

/**intellisense()
win.ui.ctrl.bkplus() = 无窗口控件,仅用于背景贴图,支持透明png图像,\n直接输出颜色或图像到窗口背景图缓存,\n因为不需要创建窗口可避免前后叠加控件后，处理不当带来的闪烁，\n适合显示静态、不会频繁变动的图像\n\nplus控件也可通过\n调用directDrawBackgroundOnly函数变为背景控件\n!winuictrlbkplus.
end intellisense**/

/**intellisense(!winuictrlbkplus)
redraw() = 刷新,会导致背景窗口重建背景图缓存\n不建议频繁调用
background = 重新指定背景图像,支持jpg,gif,png等格式,\n\n如果在这里指定ARGB格式颜色数值，\n则删除背景图像并指定backgroundColor然后刷新。\n\n读取此属性时，即使未指向图像，也不会返回backgroundColor
backgroundColor = 背景颜色,ARGB格式颜色数值\n直接修改这个属性时不会刷新，\n也不会解除background属性引用的图像。
getPos（） = 返回x,y,cx,cy,\nx,y为控件坐标,cx,cy为控件宽、高
onDrawBackground = @.onDrawBackground(hdc,rc){
	/*背景绘图以后触发此回调,\nhdc为当前绘图设备句柄,rc为控件位置*/
}
onDrawString = @.onDrawString = function(graphics,text,font,rectf,strformat,brush){
    __/*自定义输出文本,请不要删除传入参数中的GDI+对象*/
    graphics.drawString(text,font,rectf,strformat,brush);
}
foreground = 使用ARGB格式颜色数值指定前景色,不可指定图像,\nbkplus是无窗口控件，如果要叠加前景图像，添加多个bkplus控件即可
paddingRight = 前景色右边距
paddingBottom = 前景色下边距
paddingLeft = 前景色左边距
paddingTop = 前景色上边距
linearGradient = 使用此属性指定线性渐变的方向角度,负数值表示使用径向渐变,\n必须同时指定背景色、前景色才有效,指定图像后此属性无效
argbColor = ARGB格式颜色数值,用于文本输出
textRenderingHint = @.textRenderingHint = _GdipTextRenderingHint__ ;
smoothingMode = 绘图画布默认抗锯齿模式,\n默认值为_GdipSmoothingModeAntiAlias
interpolationMode = 图像缩放时的默认插值模式,\n默认值为_GdipInterpolationModeHighQualityBicubic
end intellisense**/
