import Element from './Element';
import {StringUtil} from '../../utility';



class ReportElement extends Element {
	constructor() {
		super();
		this.x = 0;
		this.y = 0; //元素真实的y值，以画布左上角为参照，元素在画布上的移动计算全采用这个值
		this.printedY = 0; //元素用以打印的y值, 此属性的值是相对于前一个区域的底线为参照，仅在生成xml时用到，不用于拿来做元素在画布上移动的依据值
		this._handlePointX = 0;
		this._handlePointY = 0;
		this.id = '';
		this.key = ''; //别名
		this.mode = ReportElement.DEF_MODE; //透明或者不透明
		this.printWhenGroupChanges = ''; 
		this.width = ReportElement.DEF_WIDTH;
		this.height = ReportElement.DEF_HEIGHT;
		this.forecolor = ReportElement.DEF_COLOR; // 当前元素使用的默认颜色
		this.backcolor = ReportElement.DEF_BGCOLOR; // 当前元素默认的背景色
		this.isRemoveLineWhenBlank = false; //当空白时是否删除线
		this.isPrintRepeatedValues = true; //是否打印重复值
		this.isPrintWhenDetailOverflows = true; //当溢出时是否打印
		this.isPrintInFirstWholeBand = true; //是否打印在区域的首行
		this.positionType = ReportElement.DEF_POSTYPE; //当前元素的位置类型
		this.stretchType = ReportElement.DEF_STRETCHTYPE; //当前元素打印时的分割类型
		this.printWhenExpression = '';
		this.property = []; //属性表达式
		this.prevChunkBaseline = 0;
		this.lineStyleOption={
            "Solid":true,
            "Dashed":false,
            "Dotted":false,
            "Double":false,
        }
		this.lineWidth=1;
		this.lineStyle="Solid";
		this.lineColor="#000000";
		this.error=false;
		this.errorImgSrc='../reportHtml/images/error.png';
	}
	
	setTrueOrdinate(referPos) {
		this.y = referPos + this.printedY;
		this.prevChunkBaseline = referPos;
	}
	
	getAbscissaConnectionPoint(target) {
		if(parseInt(target.x) == parseInt(this.x) && target.y >= this.y) {
			return {beginPoint: {x: this.x, y: this.y}, endPoint: {x: target.x, y: (target.y + target.height)}};
		} else if(parseInt(target.x) == parseInt(this.x) && target.y <= this.y) {
			return {beginPoint: {x: target.x, y: target.y}, endPoint: {x: this.x, y: (this.y + this.height)}};
		} else if(parseInt(target.x) == parseInt(this.x + this.width) && target.y >= this.y) {
			return {beginPoint: {x: (this.x + this.width), y: this.y}, endPoint: {x: target.x, y: (target.y + target.height)}};
		} else if(parseInt(target.x) == parseInt(this.x + this.width) && target.y <= this.y) {
			return {beginPoint: {x: target.x, y: target.y}, endPoint: {x: (this.x + this.width), y: (this.y + this.height)}};
		} else if(parseInt(target.x + target.width) == parseInt(this.x) && target.y >= this.y) {
			return {beginPoint: {x: this.x, y: this.y}, endPoint: {x: (target.x + target.width), y: (target.y + target.height)}};
		} else if(parseInt(target.x + target.width) == parseInt(this.x) && target.y <= this.y) {
			return {beginPoint: {x: (target.x + target.width), y: target.y}, endPoint: {x: this.x, y: (this.y + this.height)}};
		} else if(parseInt(target.x + target.width) == parseInt(this.x + this.width) && target.y >= this.y) {
			return {beginPoint: {x: (this.x + this.width), y: this.y}, endPoint: {x: (target.x + target.width), y: (target.y + target.height)}};
		} else if(parseInt(target.x + target.width) == parseInt(this.x + this.width) && target.y <= this.y) {
			return {beginPoint: {x: (target.x + target.width), y: target.y}, endPoint: {x: (this.x + this.width), y: (this.y + this.height)}}
		} else {
			return null;
		}
	}
	
	getOrdinateConnectionPoint(target) {
		if(parseInt(target.y) == parseInt(this.y) && target.x >= this.x) {
			return {beginPoint: {x: this.x, y: this.y}, endPoint: {x: (target.x + target.width), y: target.y}};
		} else if(parseInt(target.y)== parseInt(this.y) && target.x <= this.x) {
			return {beginPoint: {x: target.x, y: target.y}, endPoint: {x: (this.x + this.width), y: this.y}};
		} else if(parseInt(target.y) == parseInt(this.y + this.height) && target.x >= this.x) {
			return {beginPoint: {x: this.x, y: (this.y + this.height)}, endPoint: {x: (target.x + target.width), y: target.y}};
		} else if(parseInt(target.y) == parseInt(this.y + this.height) && target.x <= this.x) {
			return {beginPoint: {x: target.x, y: target.y}, endPoint: {x: (this.x + this.width), y: (this.y + this.height)}};
		} else if(parseInt(target.y + target.height) == parseInt(this.y) && target.x >= this.x) {
			return {beginPoint: {x: this.x, y: this.y}, endPoint: {x: (target.x + target.width), y: (target.y + target.height)}};
		} else if(parseInt(target.y + target.height) == parseInt(this.y) && target.x <= this.x) {
			return {beginPoint: {x: target.x, y: (target.y + target.height)}, endPoint: {x: (this.x + this.width), y: this.y}};
		} else if(parseInt(target.y + target.height) == parseInt(this.y + this.height) && target.x >= this.x) {
			return {beginPoint: {x: this.x, y: (this.y + this.height)}, endPoint: {x: (target.x + target.width), y: (target.y + target.height)}};
		} else if(parseInt(target.y + target.height) == parseInt(this.y + this.height) && target.x <= this.x) {
			return {beginPoint: {x: target.x, y: (target.y + target.height)}, endPoint: {x: (this.x + this.width), y: (this.y + this.height)}};
		} else {
			return null;
		}
	}
	
	toXML() {
		let str = '';
		
		str += '<reportElement ';
		str += `x = "${parseInt(this.x)}" `;
		str += `y = "${parseInt(this.printedY)}" `;
		str += `uuid = "${this.id}" `;
		str += `width = "${parseInt(this.width)}" `;
		str += `height = "${parseInt(this.height)}" `; 
		str += `forecolor = "${this.forecolor}" `;
		str += `backcolor = "${this.backcolor}" `;
		str += `isRemoveLineWhenBlank = "${this.isRemoveLineWhenBlank}" `;
		str += `isPrintWhenDetailOverflows = "${this.isPrintWhenDetailOverflows}" `;
		str += `mode = "${this.mode}" `;
		str += `isPrintInFirstWholeBand = "${this.isPrintInFirstWholeBand}" `;

		if(this.isPrintRepeatedValues) {
			str += `isPrintRepeatedValues = "${this.isPrintRepeatedValues}" `;
		}
		
		if(this.positionType != ReportElement.DEF_POSTYPE) {
			str += `positionType = "${this.positionType}" `;
		}
		
		if(this.stretchType != ReportElement.DEF_STRETCHTYPE) {
			str += `stretchType = "${this.stretchType}" `;
		}
		
		if(this.key) {
			let nodeKey=StringUtil.encodeHTML(this.key)
			str += `key = "${nodeKey}" `;
		}else if(this.key==""){
			this.key=this.text
			let nodeKey=StringUtil.encodeHTML(this.key)

			str += `key = "${nodeKey}" `;
		}
		
		if(this.printWhenGroupChanges) {
			str += `printWhenGroupChanges = "${this.printWhenGroupChanges}" `;
		}
		
		if(this.property.length != 0 || this.printWhenExpression != '') {
			str += '>\n';
			
			if(this.property.length != 0) {
				for(let i = 0, len = this.property;i < len;i++) {
					str += '<property ';
					
					for(let key in this.property[i]) {
						str += `${key} = "${this.property[i][key]}" `;
					}
					
					str += '/>\n';	
				}
			}
			
			if(this.printWhenExpression != '') {
				str += `<printWhenExpression><![CDATA[${this.printWhenExpression}]]></printWhenExpression>\n`;
			}
			
			str += '</reportElement>\n';
		} else {
			str += '/>\n';
		}
		
		return str;
	}
	
	handleReportElement(xmlNode) {
		let reportElement = {
			property: [],
			printWhenExpression: ''
		};
		
		const traversalNode = (xmlNode) => {
			//console.log(xmlNode);
			const { tagName } = xmlNode;
			//console.log(tagName);

			switch (tagName) {
				case 'property ':
					const prepareData = {};
					prepareData.name = xmlNode.getAttribute('name');
					prepareData.value = xmlNode.getAttribute('value');
					reportElement.property.push(prepareData);
					break;
				case 'printWhenExpression':
					reportElement.printWhenExpression = this.replaceText(xmlNode.childNodes[0].nodeValue);
					break;
				default:
					break;
			}
		};
		
		if(xmlNode.tagName == 'reportElement') {
			reportElement.x = parseInt(xmlNode.getAttribute('x'));
			reportElement.printedY = parseInt(xmlNode.getAttribute('y'));
			reportElement.width = parseInt(xmlNode.getAttribute('width'));
			reportElement.height = parseInt(xmlNode.getAttribute('height'));
			reportElement.id = xmlNode.getAttribute('uuid');
			reportElement.key =StringUtil.dencodeHTML(xmlNode.getAttribute('key'));
			reportElement.forecolor = xmlNode.getAttribute('forecolor') ? xmlNode.getAttribute('forecolor') : ReportElement.DEF_COLOR;
			reportElement.backcolor = xmlNode.getAttribute('backcolor') ? xmlNode.getAttribute('backcolor') : ReportElement.DEF_BGCOLOR;
			reportElement.printWhenGroupChanges = xmlNode.getAttribute('printWhenGroupChanges');
			reportElement.mode = xmlNode.getAttribute('mode') ? xmlNode.getAttribute('mode') : ReportElement.DEF_MODE;
			reportElement.isRemoveLineWhenBlank = xmlNode.getAttribute('isRemoveLineWhenBlank') === 'true';
			reportElement.isPrintRepeatedValues = xmlNode.getAttribute('isPrintRepeatedValues') === 'true';
			reportElement.isPrintWhenDetailOverflows = xmlNode.getAttribute('isPrintWhenDetailOverflows') === 'true';
			reportElement.isPrintInFirstWholeBand = xmlNode.getAttribute('isPrintInFirstWholeBand') === 'true';
			reportElement.positionType = xmlNode.getAttribute('positionType') ? xmlNode.getAttribute('positionType') : ReportElement.DEF_POSTYPE;
			reportElement.stretchType = xmlNode.getAttribute('stretchType') ? xmlNode.getAttribute('stretchType') : ReportElement.DEF_STRETCHTYPE;
			
			if(xmlNode.hasChildNodes()) {
				for(let i = 0, len = xmlNode.children.length;i < len;i++) {
					traversalNode(xmlNode.children[i]);
				}
			}
		}

		return reportElement;
	}
	
	isSelected(x, y) {
		if(x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height) {
            return true;
        }
        return false;
	}
	
	changeElementPosition(position) {
		
		if(typeof position != 'object') {
			return false;
		}
		
		let movedX, movedY = 0;
		let elementPos = {};

		if(position.x && !position.y) {
			movedX = position.x - this._handlePointX;
			elementPos.x = this.x + movedX;
			
			this.setProps({x: elementPos.x, _handlePointX: position.x});
		} else if(position.y && !position.x) {
			movedY = position.y - this._handlePointY;
			elementPos.y = this.y + movedY;
			
			this.setProps({y: elementPos.y, _handlePointY: position.y});
		} else if(position.y && position.x) {
			movedX = position.x - this._handlePointX;
			movedY = position.y - this._handlePointY;
			elementPos.x = this.x + movedX;
			elementPos.y = this.y + movedY;
			
			this.setProps({x: elementPos.x, y: elementPos.y, _handlePointX: position.x, _handlePointY: position.y});
		} else {
			return false;
		}
    }
	
	changeElementWhenDragArchor(archor, x, y) {
		let width, height, movedX, movedY;
		let elementPos = {};
		
		movedX = Math.abs(x - this._handlePointX);
		movedY = Math.abs(y - this._handlePointY);
		elementPos.x = this.x + x - this._handlePointX;
		elementPos.y = this.y + y - this._handlePointY;
		
		if(this._handlePointX >= x && this._handlePointY >= y && archor.x == 0 && archor.y == 0) {
			width = this.width + movedX;
			height = this.height + movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, x: elementPos.x, y: elementPos.y});
		} else if(this._handlePointX <= x && this._handlePointY <= y && archor.x == 0 && archor.y == 0) {
			width = this.width - movedX;
			height = this.height - movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, x: elementPos.x, y: elementPos.y});
		} else if(this._handlePointX <= x && this._handlePointY >= y && archor.x == 1 && archor.y == 0) {
			width = this.width + movedX;
			height = this.height + movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, y: elementPos.y});
		} else if(this._handlePointX >= x && this._handlePointY <= y && archor.x == 1 && archor.y == 0) {
			width = this.width - movedX;
			height = this.height - movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, y: elementPos.y});
		} else if(this._handlePointX >= x && this._handlePointY <= y && archor.x == 0 && archor.y == 1)	{
			width = this.width + movedX;
			height = this.height + movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, x: elementPos.x});
		} else if(this._handlePointX <= x && this._handlePointY >= y && archor.x == 0 && archor.y == 1) {
			width = this.width - movedX;
			height = this.height - movedY;
			
			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y, x: elementPos.x});
		} else if(archor.x == 1 && archor.y == 1) {
			width = this.width + x - this._handlePointX;
			height = this.height + y - this._handlePointY;

			this.setProps({width: width, height: height, _handlePointX: x, _handlePointY: y});
		}
	}
}

ReportElement.DEF_WIDTH = 100;
ReportElement.DEF_HEIGHT = 24; 
ReportElement.DEF_MODE = 'Opaque';
ReportElement.DEF_COLOR = "#000000";
ReportElement.DEF_BGCOLOR = "#ffffff";
ReportElement.DEF_POSTYPE = 'FixRelativeToTop';
ReportElement.DEF_STRETCHTYPE = 'NoStretch';

export default ReportElement;