import {Title, ColumnHeader, ColumnFooter, Detail, PageHeader, PageFooter, Summary} from '../chunk';
import {StaticText, TextField, Rectangle, Line, Ellipse,imgEle,CurrentDate,PageNumber,Chart,SubReport} from '../element';
import {Api,Graphics, Sequence, StringUtil, Archor, AuxiliaryLine, Resources} from '../../utility';
import Menu from './Menu';
import Tree from './Tree';
import TreeMenu from './TreeMenu';
class ReportPanel {
	constructor(canvas) {
		this.canvas  = canvas;
		this.g = new Graphics(canvas.getContext('2d'));
		this.chunk = [];
		this.elem = null;  //元素在未添加进区域的临时存放地
		this._currToChunk = null; //当前选择区域
		this._currToElem = null; //当前选择元素
        this.selectedArchor = null; //是否有被选中的锚点，用于移动时拖拽元素
		this._statues = ReportPanel.ACTION_NORMAL; //鼠标状态值
		this.width = this.canvas.width; 
		this.height = this.canvas.height;
		this.pageWidth=0;
		this.pageHeight=842;
		this._applicationid = null;
		this.isAllowDraw = false; //画布绘图开关
		this.id = Sequence.createUuid();
		this.myId = null,
		this.reportName = '';
		this.field = [];
		this.variables=[];
		this.variable=[];//保存variable的子节点
		this.queryString = '';
		this.tree2=Tree.getInstance();
		this.chartNoData=false;
		this.noChunkElement=[];
		this.canvasHeightError=false;
		this.parameters=[];
		this.parameter=[];//保存parameter的子节点
		this.filterexpression="";//给子报表组件用的
		this.subReportId="";//子报表id
		this.isIgnorePagination=false;
	}
	
	setProps(newProps) {
		Object.assign(this, newProps);
	}
	
	getProp(prop) {
		return this[prop];
	}
	
	//获取当前正在编辑的区域或元素
	getCurrToEdit() {
		return this._currToChunk || this._currToElem || null;
	}
	
	//清空正在编辑的元素和区域
	clearCurrToEdit() {
		this._currToChunk = null;
		
		if(this._currToElem) {
			this._currToElem.setProps({isOpenArchor: false});
		}
		
		this._currToElem = null;
	}
	
	/**
     * 当鼠标松开时，将元素添加到所放置的对应区域里
     * @param elem 要添加的元素
     */
	addElementToChunk(elem) {
		//console.log(elem)
		let haveChunk=false;
        for(let i = 0, len = this.chunk.length;i < len;i++) {
            if(this.chunk[i].isInChunk(elem)) {
				this.chunk[i].addElement(elem);
				haveChunk=true;
				elem.error=false;
				//console.log(this.chunk[i])
				this.refreshTreeList();
                return;
            }
        }
        if(!haveChunk){
        	//console.log("haveChunk"+haveChunk)
			if(this.noChunkElement.length>0){
				this.noChunkElement.forEach((val,ind)=>{
					if(elem.id!=val.id){
						elem.error=true;
						elem.belong="";
						this.delElementFromChunk(elem)
						this.noChunkElement.push(elem);
					}
				})
			}else{
				elem.error=true;
				elem.belong="";
				this.delElementFromChunk(elem)
				this.noChunkElement.push(elem);
			}

		}
	}
	
	//删除区域内对应元素
	delElementFromChunk(elem) {
		for(let i = 0, len = this.chunk.length;i < len;i++) {
            if(this.chunk[i].getClassName() == elem.getProp('belong')) {
				this.chunk[i].delElement(elem);
                return;
            }
        }
	}
	
	paint() {
		const chunk = this.chunk;
		const g = this.g;
		let nowHeight=0;
		//清空画布
		g.save();
		g.setColor(Resources.COLOR.white);
		g.fillRect(0, 0, this.width, this.height);
		g.restore();
		//console.log(chunk)
		//绘制区域
		if(chunk.length > 0) {
			for(let i = 0;i < chunk.length;i++) {
				if(chunk[i].getProp('height') <= 0) {
					continue;
				} else {
					nowHeight += chunk[i].getProp('height');
					// const move = nowHeight-chunk[i].top;
					// chunk[i].top=nowHeight;
					// chunk[i].changeElementPosWithTop(move);

					chunk[i].paint(g);	
					
				}
			}
		}
		if(this.noChunkElement.length>0){
			console.log(this.noChunkElement.length)
			this.noChunkElement.forEach(function(val,ind){
				val.paint(g);
			})
		}
		//绘制尚未放入区域的移动中的元素
		if(this.elem != null) {
			this.elem.paint(g);
		}
		
		//绘制辅助线
		if(AuxiliaryLine.getInstance().getProp('points')) {
			AuxiliaryLine.getInstance().paint(g);
		}
		if(this._currToElem){
			let archor = Archor.getInstance();
			let openArchor = [{x: 0, y: 0}, {x: 1, y: 0}, {x: 1, y: 1}, {x: 0, y: 1}]; //以当前元素左上角为坐标系，得(0, 0)为左上角，依次类推
			let params = {x: this._currToElem.getProp('x'), y: this._currToElem.getProp('y'), targetW: this._currToElem.getProp('width'), targetH: this._currToElem.getProp('height'), openArchorPos: openArchor};
			archor.setProps(params);
			archor.paint(g);
		}
		g.clearRect(0,nowHeight,this.width,this.canvas.height-nowHeight);
	}
	
	repaint() {
		this.paint();
	}
	
	addStaticText() {
		let elem = new StaticText();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addCurrentDate() {
		let elem = new CurrentDate();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addPageNumber() {
		let elem = new PageNumber();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addImage(uploadImage) {
		let elem = new imgEle();
		this.elem = elem;
		this.elem.uploadImage=uploadImage;
		//console.log(elem)
		this.isAllowDraw = true;
	}
	
	addVariable(text,field=null,opt=null) {
		
		let elem = new TextField();
		elem.text="$V{"+text+"}";
		elem.field=field;
		elem.option=opt;
		elem.scope="Variables"
		//console.log(elem)
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addParameter(text) {
		
		let elem = new TextField();
		elem.text="$P{"+text+"}";
		elem.scope="Parameter"
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addTextField(text) {
		let elem = new TextField();
		this.elem = elem;
		this.isAllowDraw = true;
		
		if(text) {
			elem.setProps({text: `$F{${text}}`});
		}
	}
	
	addLine() {
		let elem = new Line();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	
	addRectangle() {
		let elem = new Rectangle();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	
	addEllipse() {
		let elem = new Ellipse();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addChart(){
		let elem = new Chart();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	addSubReport(){
		let elem = new SubReport();
		this.elem = elem;
		this.isAllowDraw = true;
	}
	delElement() {
		this.elem = null;
		this.isAllowDraw = false;
	}
	
	init() {
		
		this.loadChunk();
		//初始化区域之后，variable开始有值，把他保存下来;
		
		this.canvas.onmousemove = (e) => {
           this.handleMouseMove(e);
		};
        
        // this.canvas.onclick = (e) => {
            // this.mouseClick(e);
        // };
		
        this.canvas.onmousedown = (e) => {
            this.handleMouseDown(e);
        };
		
        this.canvas.onmouseup = (e) => {
            this.handleMouseUp(e);
        };
		
		this.canvas.onkeydown = (e) => {
            this.handleKeyDown(e);
		};
		//this.canvas.addEventListener('keydown', this.handleKeyDown, true);
		
        // this.canvas.onmouseover = (e) => {
            //this_mouseEntered(e);
        // };

		this.paint();
	}

	//初始化区域
	loadChunk() {
		if(this.chunk.length == 0) {
			//this.chunk.push(new Variables(0, 0));
			this.chunk.push(new Title(this.width, this.height));
			this.chunk.push(new PageHeader(this.width, this.height));
			this.chunk.push(new ColumnHeader(this.width, this.height));
			this.chunk.push(new Detail(this.width, this.height));
			this.chunk.push(new ColumnFooter(this.width, this.height));
			this.chunk.push(new PageFooter(this.width, this.height));
			this.chunk.push(new Summary(this.width, this.height));
			
			//console.log(this.chunk)
		} else {
			return false;
		}
	}
	//改变画布宽高的时候改变各区域的宽高
	changeChunkSize(size){
		let len=this.chunk.length;

		for(let i=0;i<len;i++){
			this.chunk[i].setProps(size)
		}
	}
	handleMouseMove(e) {
		
		let {x, y} = this.getLocationByCanvas(this.canvas, e.clientX, e.clientY);
		if(!this.isAllowDraw) {

			const result = this.chkChunkBaseLine(y);
			
			if(result) {
				this.changeStatues(ReportPanel.ACTION_IN_BASELINE);

				return;
			} else {
			    //Archor类为单例模式，只有一个实例
			    const archorPos = Archor.getInstance().getArchorPosition(x, y);

			    if(archorPos) {
                    if(archorPos.x == 0 && archorPos.y == 0) {
                        this.changeStatues(ReportPanel.ACTION_ARCHOR_UPPER_LEFT);
                        return;
                    } else if(archorPos.x == 1 && archorPos.y == 0) {
                        this.changeStatues(ReportPanel.ACTION_ARCHOR_UPPER_RIGHT);
                        return;
                    } else if(archorPos.x == 1 && archorPos.y == 1) {
                        this.changeStatues(ReportPanel.ACTION_ARCHOR_LOWER_RIGHT);
                        return;
                    } else if(archorPos.x == 0 && archorPos.y == 1) {
                        this.changeStatues(ReportPanel.ACTION_ARCHOR_LOWER_LEFT);
                        return;
                    }
                } else {
                    const elem = this.chkSelectedElement(x, y);

                    if(elem) {
                        this.changeStatues(ReportPanel.ACTION_IN_ELEMENT);
                        return;
                    } else {
                        this.changeStatues(ReportPanel.ACTION_NORMAL);
                        return;
                    }
                }
			}
			
			return false;
		} else {

			if(this.elem != null) {
				//console.log(this.elem)
				const auxiliaryLinePoints = AuxiliaryLine.getInstance().getProp('points');
				const movedX = Math.abs(this.elem.getProp('x') - x);
				const movedY = Math.abs(this.elem.getProp('y') - y);
				
				if(auxiliaryLinePoints && auxiliaryLinePoints.abscissa && !auxiliaryLinePoints.ordinate && movedX < 3) {
					this.elem.setProps({y: y});
				} else if(auxiliaryLinePoints && !auxiliaryLinePoints.abscissa && auxiliaryLinePoints.ordinate && movedY < 3) {	
					this.elem.setProps({x: x});
				} else if(auxiliaryLinePoints && auxiliaryLinePoints.abscissa && auxiliaryLinePoints.ordinate && (movedY < 3 && movedX < 3)) {
					return false;
				} else {
					this.elem.setProps({x: x, y: y});
				}
				
				const points = this.getDrawAuxiliaryLinePoint(this.elem);
					
				if(points) {
					AuxiliaryLine.getInstance().setProps({points: points});
				} else {
					AuxiliaryLine.getInstance().setProps({points: null});
				}
			} else if(this._currToChunk && this._currToChunk.isSelectedBaseline) {
				let nowCanvasHeight=this.calculationNowCanvasHeight();
				// console.log(y)
				let groupHeight=0;
				if(this.chunk.length>7){
					this.chunk.forEach(elm=>{
						if(elm.scope=="GroupHeader" ||elm.scope=="GroupFooter"){
							groupHeight+=elm.height;
						}
					})
				}
				if(y-this._currToChunk.top+nowCanvasHeight>this.pageHeight+groupHeight+20){

					this._currToChunk.changeSelectedChunk(y);
					this.repaint();
					this.handleMouseUp(e)
					alert("画布高度必须小于页面高度")
					return false;
				}
				this._currToChunk.changeSelectedChunk(y);

			} else {
                if(this.selectedArchor && this._currToElem) {
					console.log(1)
                    this._currToElem.changeElementWhenDragArchor(this.selectedArchor, x, y);
                } else if(this._currToElem) {
					const auxiliaryLinePoints = AuxiliaryLine.getInstance().getProp('points');
					const movedX = Math.abs(this._currToElem.getProp('_handlePointX') - x);
					const movedY = Math.abs(this._currToElem.getProp('_handlePointY') - y);
					
					if(auxiliaryLinePoints && auxiliaryLinePoints.abscissa && !auxiliaryLinePoints.ordinate && movedX < 5) {
					    this._currToElem.changeElementPosition({y: y});
					} else if(auxiliaryLinePoints && !auxiliaryLinePoints.abscissa && auxiliaryLinePoints.ordinate && movedY < 5) {	
						this._currToElem.changeElementPosition({x: x});
					} else if(auxiliaryLinePoints && auxiliaryLinePoints.abscissa && auxiliaryLinePoints.ordinate && (movedY < 5 && movedX < 5)) {
						return false;
					} else {
						this._currToElem.changeElementPosition({x: x, y: y});
					}
					
					const points = this.getDrawAuxiliaryLinePoint(this._currToElem);
					
					if(points) {
						AuxiliaryLine.getInstance().setProps({points: points});
					} else {
						AuxiliaryLine.getInstance().setProps({points: null});
					}
					let isnearBase;
					
					for(let i=0;i<this.chunk.length;i++){
						isnearBase=this.chunk[i].elemIsOnLines(y,this._currToElem.height);
						if(isnearBase){
							this._currToElem.setProps({y: isnearBase});
							
							break;
						}
					}

                } else {
                    return false;
                }
			}

			this.repaint();	
		}
		console.log("move",this._currToChunk);
	}
	
	handleMouseUp(e) {
		let that=this;
		this.isAllowDraw = false;
		this.selectedArchor = null;
		AuxiliaryLine.getInstance().setProps({points: null});
        let {x, y} = this.getLocationByCanvas(this.canvas, e.clientX, e.clientY);
		const tree = Tree.getInstance();
		if(this.elem != null) {
			let api = new Api();
			let cancel=true;
			if(this.elem.uploadImage){
				this.elem.uploadImage.trigger("click");
				this.elem.uploadImage.off("change").on("change",function(){
					//cancel=false;
					let formData = new FormData();
					formData.append("file",this.files[0]);
					let src1=api.getImgAddr(formData);
					if(src1){
						that.elem.srcT='"'+src1+'"';
						let src2=src1.substr(src1.indexOf("/uploads"));
						//let src2=src1.replace(/[CDEFGHI]\:\/project\/obpm4\.21\/obpm\-demo/ ,"../../../designer");
						src2="../../../designer"+src2;
						that.elem.src=src2;

					}
					that.addElementToChunk(that.elem);
					that.repaint();

					that.elem = null;
				})

				// if(cancel){
				// 	that.addElementToChunk(that.elem);
				// 	that.repaint();
				// 	that.elem = null;
				// }
			}else if(this.elem.text=="chart"&&this.elem.chartType==""){
				let url =  "chooseChart.html";
				OBPM.dialog.show({
					opener:window,
					width: 300,
					height: 400,
					url: url,
					args: {},
					title: '选择图表',
					close: function(props) {
						that.elem.chartType=props.chart;
						that.elem.chartTypeChina=props.chartChina;
						that.elem.src=props.imgSrc;
						that.addElementToChunk(that.elem);
						that.repaint();
						that.elem=null;
					}
				});

			}else{
				this.addElementToChunk(that.elem);
				this.elem = null;
			}

		} else if(this._currToChunk != null && this._currToChunk.isSelectedBaseline) {
			this._currToChunk.changeSelectedChunk(y);	
            this._currToChunk.setProps({isSelectedBaseline: false});

			const move = this._currToChunk.getMoveDistance();

            //重计算容器的高
			this.recalculationContainerHeight();
			//改变区域大小及后面区域元素的相对于现在的位置
			this.changeChunkSizeWithBaseLine(move);
		} else if(this._currToElem){
			this.resetElementToChunk(this._currToElem);
		} else {
			
		}
		
		this.repaint();
		tree.render();
	}

	handleMouseDown(e) {
		// yx判断不是中文才重新执行
    if (getCookie("designerLanguage") != "zh") {
      // 重新渲染多语言
      jQuery(document).ready(function () {
        let lang = getCookie("designerLanguage");
        // clearTimeout(timer)
        jQuery.i18n.properties({
          //加载资浏览器语言对应的资源文件
          name: "strings", //资源文件名称
          path: "i18n/", //资源文件路径
          language: lang,
          cache: false,
          mode: "map", //用Map的方式使用资源文件中的值
          callback: function () {
            //加载成功后设置显示内容
            for (let i in $.i18n.map) {
              $('[data-lang="' + i + '"]').text($.i18n.map[i]);
            }
            // document.title = $.i18n.map['title'];
          },
        });
      });
    }
		//console.log(this._currToElem)
		const {x, y} = this.getLocationByCanvas(this.canvas ,e.clientX, e.clientY);
		
		if(e.button <= 0) {
			const menu = Menu.getInstance();
			
			if(menu.getProp('hasMenu') && menu.getProp('isShowMenu')) {
				menu.hideMenu();
			}
			
			this.isAllowDraw = true;
			
			const archorPos = Archor.getInstance().getArchorPosition(x, y);
			
			if(this._currToElem && archorPos) {
				//console.log(1);
			    this.selectedArchor = archorPos;
                this._currToElem.setProps({_handlePointX: x, _handlePointY: y});
                return false;
            } else if(this._currToElem != null && this._currToElem.isSelected(x, y)) {
            	//console.log(2)
				this._currToElem.setProps({_handlePointX: x, _handlePointY: y});
			} else {
				//console.log(3)
                let em = this.chkSelectedElement(x, y);
                
				if(em != null && this._currToElem != null && this._currToElem.id != em.id) {
					
                    this._currToElem.setProps({isOpenArchor: false});
                    this._currToElem = em;
                    this._currToElem.setProps({_handlePointX: x, _handlePointY: y, isOpenArchor: true});
                } else if(em != null && this._currToElem == null) {
                	
                    this._currToElem = em;
                    this._currToChunk = null;
                    this._currToElem.setProps({_handlePointX: x, _handlePointY: y, isOpenArchor: true});
                } else {
                    let ck = this.chkSelectedChunk(y);
                    let ckBaseLine = this.chkChunkBaseLine(y);

                    if(this._currToElem != null) {
                        this._currToElem.setProps({isOpenArchor: false});
                        this._currToElem = null;
                    }

                    if(ck != null && ckBaseLine) {
                    	//点下边线部分
                        this._currToChunk = ck;

                        const top = this._currToChunk.getProp('top');
                        const height = this._currToChunk.getProp('height');

                        this._currToChunk.setProps({_beforeMovePos: top, _beforeMoveHeight: height, isSelectedBaseline: true});
                        console.log(this._currToChunk)
                    } else if(ck != null && !ckBaseLine) {
                    	//点击区域的空白部分
                        this._currToChunk = ck;
                        this._currToChunk.setProps({isSelectedBaseline: false});
                    } else {
                        return false;
                    }
                }
				
            }
		} else if(e.button == 2) {
			const target = e.target;
			const menu = Menu.getInstance();
			
			this.stopElementDefaultMenu(target);
			
			if(this._currToElem && this._currToElem.isSelected(x, y)) {
				menu.setProps({target: e, report: this});
				menu.showMenu();
			} else {
				menu.hideMenu();
			}
		} else {
			return false;
		}
	}
	
	handleKeyDown(e){
		e.preventDefault();
		this.isAllowDraw=false;
		if(this._currToElem){
			let code=e.keyCode;
			switch(code){
				case 38:
					this._currToElem.y-=1;
				break;
				case 40:
					this._currToElem.y+=1;
				break;
				case 37:
					this._currToElem.x-=1;
				break;
				case 39:
					this._currToElem.x+=1;
				break;
			}
			this.repaint();
			
		}
	}

    /**
     * 将画布上的区域及元素的类属性转为xml
     * @return 返回拼接的xml字符串
     */
	toXML() {
		if(this.noChunkElement.length>0){
			alert("请将区域中未放置正确的组件重新放置")
			return "haveNoChunkElement";
		}
		
		let str = `<jasperReport name="${this.reportName}" xmlns = "http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"  pageWidth = "`+this.width+`" pageHeight = "`+this.pageHeight+`" columnWidth = "555" leftMargin = "0" rightMargin = "0" topMargin = "0" bottomMargin = "0" isIgnorePagination="${this.isIgnorePagination}" isFloatColumnFooter="true" uuid = "${this.id}">\n`;
		str += '<property name="ireport.zoom" value="1.0"/>\n';
		str += '<property name="ireport.x" value="0"/>\n';
		str += '<property name="ireport.y" value="0"/>\n';
		
		if(this.parameter.length>0){
			for(let k = 0;k < this.parameter.length;k++) {
				str+=`<parameter name="`+this.parameter[k].text+`" class="`+this.parameter[k].cls+`"/>\n`
			}
		}

		if(this.queryString != '') {
			str += `<queryString language="SQL"><![CDATA[${this.queryString}]]></queryString>\n`;
		}
		if(this.field.length > 0) {
			for(let i = 0;i < this.field.length;i++) {
				str += `<field name="${this.field[i].columnName}" class="${this.field[i].columnClassName}">\n`;
				str +=`<fieldDescription><![CDATA[`+this.field[i].description+`]]></fieldDescription>\n`
				str +=`</field>\n`
			}
		}

		if(this.variable){
			for(let j = 0;j < this.variable.length;j++) {
				if(this.variable[j].option=='Nothing' && this.variable[j].option=="null"){
					str +=`<variable name="${this.variable[j].text}" class="${this.variable[j].cls}" resetType="${this.variable[j].resetType}" >
					<variableExpression><![CDATA[${this.variable[j].varExpression}]]></variableExpression>\n`
				}else{
					if(this.variable[j].resetGroup!="" &&this.variable[j].resetType=="Group"){
						str +=`<variable name="${this.variable[j].text}" class="${this.variable[j].cls}" resetType="${this.variable[j].resetType}" calculation="${this.variable[j].option}"  resetGroup="${this.variable[j].resetGroup}">\n
						<variableExpression><![CDATA[${this.variable[j].varExpression}]]></variableExpression>\n`
					}else{
						str +=`<variable name="${this.variable[j].text}" class="${this.variable[j].cls}" resetType="${this.variable[j].resetType}" calculation="${this.variable[j].option}">\n
						<variableExpression><![CDATA[${this.variable[j].varExpression}]]></variableExpression>\n`
					}
					
				}
				str +=`</variable>\n`
			}
		}
		if(this.filterexpression!=""){
			str += `<filterExpression><![CDATA[`+this.filterexpression+`]]></filterExpression>\n`
		}
		if(this.chunk.length>7){
			let id=null;
			let haveGroupNoName=false;
			this.chunk.forEach(elm=>{
				if(elm.scope=="GroupHeader" && id==null){
					if(elm.name=="" || !elm.name){
						haveGroupNoName=true;
					}
					id=elm.tip;//拿到之前添加的时候给的唯一标识时间戳，来拿footer
					str += "<group name=\""+elm.name+"\">\n";
					str+=elm.toXML();
				}

				if(id){
					for(let c=0;c<this.chunk.length;c++){
						if(this.chunk[c].tip==id && this.chunk[c].scope=="GroupFooter"){
							id=null;
							str +=this.chunk[c].toXML();
							str +="</group>\n";
							break;
						}

					}
				}
			})
			if(haveGroupNoName){
				return "haveGroupNoName";
			}
			
		}
		
		str += '<background><band splitType="Stretch"/></background>\n';
		//console.log(this.chunk[0].element)
		for(let k = 0;k < this.chunk.length;k++) {
			if(this.chunk[k].scope!="GroupHeader" && this.chunk[k].scope!="GroupFooter")
			str += this.chunk[k].toXML();
		}
        for(let a = 0;a < this.chunk.length;a++) {
			if(this.chunk[a].element.length>0){
				for(let b=0;b<this.chunk[a].element.length;b++){
					if(this.chunk[a].element[b] instanceof Chart){
						if(!this.chunk[a].element[b].chartDateNull){
							return "chartNoData";
						}
					}
				}
			}

        }
		str += '</jasperReport>\n';
		//console.log(str)
		return str;
	}

    /**
     * 获取鼠标在画布上的位置
     * @canvas 画布元素
     * @param x 鼠标x轴位置
     * @param y 鼠标y轴位置
     * @return 鼠标在画布上的位置
     */
	getLocationByCanvas(canvas, x, y) {  
		var bbox = canvas.getBoundingClientRect();  
		return {  
			x: (x - bbox.left) * (canvas.width / bbox.width),   
			y: (y - bbox.top) * (canvas.height / bbox.height)  
		};  
	}
	
    /**
     * 获取绘画辅助线的点
     * @target 当前画布中被选中的元素，以此元素的顶点作为基准寻找画辅助线的点
     * @return 绘画辅助线的点，找不到时为空
     */
	getDrawAuxiliaryLinePoint(target) {
		let point = {};
		
		if(!target) {
			return false;
		}
		
        for(let i = 0, len = this.chunk.length; i < len; i++) {
			const result = this.chunk[i].getElementConnectionPoint(target);
			
			if(result && result.abscissa && !point.abscissa) {
				point.abscissa = result.abscissa;
			}
					
			if(result && result.ordinate && !point.ordinate) {
				point.ordinate = result.ordinate;
			}

			if(point.abscissa && point.ordinate) {
				return point;
			}			
        }
		
		if(!point.abscissa && !point.ordinate) {
			return null;
		} else {
			return point;
		}
	}

	/**
     * 检查鼠标是否选中以及是否经过元素
	 * @param x 鼠标x轴位置
	 * @param y 鼠标y轴位置
     * @return 返回所选或所经过元素，没找到时返回null
	 */
	chkSelectedElement(x, y) {
		
        for(let i = 0, len = this.chunk.length; i < len; i++) {
			let element = this.chunk[i].hasSelectedElement(x, y);
			//console.log(element);
			if(element) {
				return element;
			}
        }
		for(let i = 0, len = this.noChunkElement.length; i < len; i++) {

			//console.log(element);
			if(this.noChunkElement[i].isSelected(x,y)) {
				return this.noChunkElement[i];
			}
		}
		
        return null;
	}
	
	/**
     * 检查鼠标是否选中以及是否经过区域
	 * @param position 鼠标y轴位置
     * @return 返回所选或所经过区域，没找到时返回null
	 */
	chkSelectedChunk(pos) {
		for(let i = 0, len = this.chunk.length;i < len;i++) {
			if(this.chunk[i].isSelected(pos)) {
				return this.chunk[i];
			}
		}
		
		return null;
	}
	
	/**
     * 检查鼠标位置是否在区域的底线上
	 * @param position 鼠标y轴位置
     * @return 返回所选或所经过区域底线，没找到时返回null
	 */
	chkChunkBaseLine(pos) {
		//console.log(111)
		for(let i = 0, len = this.chunk.length;i < len;i++) {
			if(this.chunk[i].isInChunkBaseline(pos)) {
				return true;
			}
		}
		
		return null;
	}
	
	/**
     * 是否移动元素(元素是否跨区域)
	 * @param element 需要移动的元素
	 */
	isMoveElement(element) {
		for(let i = 0, len = this.chunk.length;i < len;i++) {
			if(this.chunk[i].isBelong(element)) {
				return false;
			}
		}
		
		return true;
	}
	
	/**
     * 根据区域底线变化改变区域的大小
	 * @param position 传入当前鼠标的位置
	 */
	changeChunkSizeWithBaseLine(pos) {
		for(let i = 0, len = this.chunk.length;i < len;i++) {
			if(this._currToChunk && this._currToChunk.scope == this.chunk[i].scope) {
				if(this._currToChunk.scope=="GroupHeader" || this._currToChunk.scope=="GroupFooter" ){
					if(this._currToChunk.name==this.chunk[i].name){
						for(let j = i + 1;j < this.chunk.length;j++) {
							this.chunk[j].setTop(pos);
							this.chunk[j].changeElementPosWithTop(pos);
						}	
					}else{
						break;
					}
				}else{
					for(let j = i + 1;j < this.chunk.length;j++) {
						this.chunk[j].setTop(pos);
						this.chunk[j].changeElementPosWithTop(pos);
					}
				}	
				break;
			}				
		}
	}
	
	/**
	 * 改变鼠标状态
	 * @param statues 传入对应的状态码
	 */
	changeStatues(statues) {

		this._statues = statues;
		switch (this._statues) {
			case ReportPanel.ACTION_NORMAL:
				this.canvas.style.cursor = "default";
				break;
			case ReportPanel.ACTION_IN_ELEMENT:
				this.canvas.style.cursor = "move";
				break;
			case ReportPanel.ACTION_IN_BASELINE:
				this.canvas.style.cursor = "n-resize";
				break;
			case ReportPanel.ACTION_ARCHOR_UPPER_LEFT:
				this.canvas.style.cursor = 'nw-resize';
				break;
			case ReportPanel.ACTION_ARCHOR_UPPER_RIGHT:
				this.canvas.style.cursor = 'ne-resize';
				break;
			case ReportPanel.ACTION_ARCHOR_LOWER_LEFT:
				this.canvas.style.cursor = 'sw-resize';
				break;
			case ReportPanel.ACTION_ARCHOR_LOWER_RIGHT:
				this.canvas.style.cursor = 'se-resize';
				break;
			default:
				this.canvas.style.cursor = "initial";
				break;
		}
	}

    /**
     * 当区域变化时，重计算画布以及其父元素的高度
     * @param moveDistance 移动距离
     */
	recalculationContainerHeight() {
		let h = 0;

		for(let i = 0, len = this.chunk.length;i < len;i++) {
			h += this.chunk[i].getProp('height');
		}

		this.canvas.height = h+20;
		this.canvas.parentNode.style.height  = h + 'px';
		this.setProps({height: h});
	}
	//计算当前的画布高度
	calculationNowCanvasHeight() {
		let h = 0;

		for(let i = 0, len = this.chunk.length;i < len;i++) {
			h += this.chunk[i].getProp('height');
		}
		return h+20;
	}
	//重置所有区域相对于画布顶部的基线的位置，主要用于解析完xml后根据各区域高度的变化设置top值来决定基线位置
	resetChunkBaseline() {	
		for(let i = 0, len = this.chunk.length;i < len;i++) {
			const defaultH = this.chunk[i].getProp('defaultH');
			const height = this.chunk[i].getProp('height');
			
			if(defaultH != height) {
				const diffVal = height - defaultH;
				
				for(let j = i; j < this.chunk.length;j++) {
					this.chunk[j].setTop(diffVal);
				}
			}

			//在当前区域的top和height值都设置完成后，重置元素相对于画布左上角的y轴位置
			this.chunk[i].resetElementTrueOrdinate();
		}

		//重计算外层容器即canvas和其父元素的高
		this.recalculationContainerHeight();
	}
	
	//重新确认元素所属区域
	resetElementToChunk(elem) {
		if(this.isMoveElement(elem) && !elem.isChunk) {

			this.delElementFromChunk(elem);
			this.addElementToChunk(elem);
			if(!elem.error){
				elem.error=false;
				// this.noChunkElement.concat(this.noChunkElement.slice[0,elem.errorInd-1],this.noChunkElement.slice[elem.errorInd,this.noChunkElement.length])
				// this.noChunkElement[elem.errorInd]
				let errorInd;
				this.noChunkElement.forEach(function(val,ind){
					if(val.id==elem.id){
						errorInd=ind;
					}
				})
				//this.noChunkElement.concat(this.noChunkElement.slice(0,errorInd-1),this.noChunkElement.slice(errorInd,this.noChunkElement.length))
				this.noChunkElement.splice(errorInd,1);
			}else{

			}
		} else {
			return false;
		}
	}
	
	/**
	 * 将画布上的区域及元素转变为树结构，用以构建树形菜单
	 * @return 返回树形格式的数据
	 */
	transformToTree() {
		const chunk = this.chunk;
		const fields = this.getFieldToTree();
		const Variable=this.getVariableToTree();
		const parameters = this.getParameterToTree();
		//console.log(chunk);

		let tree = [];
		let reportMain={
			text: this.reportName,
			collapseIcon:"glyphicon glyphicon-euro",
			emptyIcon:"glyphicon glyphicon-th-list",
			scope:"report",
			nodes:[],
		}
		reportMain.nodes.push(fields);
		reportMain.nodes.push(Variable);
		reportMain.nodes.push(parameters);

		for(let i = 0, len = chunk.length;i < len;i++) {
			let data = chunk[i].getNodeConfigInfo();
			reportMain.nodes.push(data);
		}
		tree.push(reportMain)

		//console.log(tree)
		return tree;
	}
	
	//将元素添加到区域时刷新树形菜单
	refreshTreeList() {
		const tree = Tree.getInstance();
		tree.render();
	}

	//屏蔽浏览器默认的右键菜单
	stopElementDefaultMenu(target) {
		target.oncontextmenu = (ev) => {
			return false;   //屏蔽右键菜单
		}
	}

	/**
	 * 处理从后台拿到的报表的基本配置信息
	 */
	handleBasicConf(config) {
		if(config instanceof Array && config.length != 0) {
			let field = [];
			
			for(let i = 0;i < config.length;i++) {
				field[i] = {};
				field[i].columnName = config[i].columnName;
				field[i].columnClassName = config[i].columnClassName;
				field[i].description=config[i].columnLabel;
				field[i].scope="field";
			}
			
			this.setProps({field: field});
		}
	}

	/**
	 * 将后台得到的数据源字段转变为树的形式
	 * @return 树形格式的数据
	 */
	getFieldToTree() {
		let fields = {
			text: '字段',
			collapseIcon:"glyphicon glyphicon-euro",
			emptyIcon:"glyphicon glyphicon-th-list",
			scope:"fields"
		};
		//console.log(this.field)
		if (this.field.length > 0) {
			fields.nodes = [];

			for (let i = 0, len = this.field.length; i < len; i++) {
				const data = {
					text: this.field[i].columnName,
					icon: 'glyphicon glyphicon-text-width',
					isField: true,
					scope:"field",
					name:this.field[i].columnName,
					fieldClass:this.field[i].columnClassName,
					description:this.field[i].description,
				};

				fields.nodes.push(data);
			}
		}
		//console.log(fields)
		if(this.field.length>0){
			fields.collapseIcon = 'glyphicon glyphicon-euro';
		}else{
			fields.icon='glyphicon glyphicon-cloud';
		}
		return fields;
	}
	
	getVariableToTree(){
		/**
		 * variables存储的是从打开页面后再增加的变量
		 * variable存储的是已经保存好的变量
		 * 先对两个进行处理，将varibales存储的和variable的进行整合
		 * 然后生成树节点
		 *  */
		this.variables=this.tree2.backTreeMenu().backTreeMenu();
		let Variables={
			text: '变量',
			scope:"Variables",

		};
		let copyVariable=[...this.variable];
		if(this.variable&&this.variables.nodes){
			if(this.variable.length==0){
				this.variable=this.variables.nodes;
			}else{
				for(let j = 0,len2 = this.variables.nodes.length; j < len2; j++){
					let have=false;
					for(let i = 0,len = copyVariable.length; i < len; i++){
						if(copyVariable[i].idOne==this.variables.nodes[j].idOne){
							have=true;
							break;
						}
					}
					if(!have){
						this.variable.push(this.variables.nodes[j])
					}
				}
			}
		}
			
		if(!Variables.nodes&&this.variable.length>0){
			Variables.nodes=[];
		}
		
		for (let i = 0,len = this.variable.length; i < len; i++) {
			const data = {
				text: this.variable[i].text,
				scope:this.variable[i].scope,
				field:this.variable[i].field,
				option:this.variable[i].option,
				cls:this.variable[i].cls,
				resetType:this.variable[i].resetType,
				icon: 'glyphicon glyphicon-text-width',
				isVariable: true,
				idOne:this.variable[i].idOne,
				isField:this.variable[i].isField,
				resetGroup:this.variable[i].resetGroup,
				varExpression:this.variable[i].varExpression
			};

			Variables.nodes.push(data);
		}
		if(Variables.nodes&&Variables.nodes.length>0){
		}else{
			Variables.icon='glyphicon glyphicon-cloud';
		}
		
		return Variables;
	}
	getParameterToTree(){
		this.parameters=this.tree2.backTreeMenu().backTreeMenu2();
		let Parameters={
			text: '参数',
			scope:"Parameters",

		};
		let copyParameter=[...this.parameter];
		if(this.parameter&&this.parameters.nodes){
			if(this.parameter.length==0){
				this.parameter=this.parameters.nodes;
			}else{
				for(let j = 0,len2 = this.parameters.nodes.length; j < len2; j++){
					let have=false;
					for(let i = 0,len = copyParameter.length; i < len; i++){
						if(copyParameter[i].idOne==this.parameters.nodes[j].idOne){
							have=true;
							break;
						}
					}
					if(!have){
						this.parameter.push(this.parameters.nodes[j])
					}
				}
			}
		}
			
		if(!Parameters.nodes&&this.parameter.length>0){
			Parameters.nodes=[];
		}
		
		for (let i = 0,len = this.parameter.length; i < len; i++) {
			const data = {
				text: this.parameter[i].text,
				scope:this.parameter[i].scope,
				cls:this.parameter[i].cls,
				icon: 'glyphicon glyphicon-text-width',
				isVariable: true,
				idOne:this.parameter[i].idOne,
			};

			Parameters.nodes.push(data);
		}
		if(Parameters.nodes&&Parameters.nodes.length>0){
		}else{
			Parameters.icon='glyphicon glyphicon-cloud';
		}
		
		return Parameters;
	}
	
	//全局唯一一个给this,field赋值的地方
	//解析xml字段上属于自身的属性
	
	parseOwnProperty(xmlNode) {
		const { tagName } = xmlNode;
		//console.log(xmlNode);
		switch(tagName) {
			case 'queryString':
				const text = StringUtil.replaceText(xmlNode.childNodes[0].nodeValue);
				this.queryString = text;
				break;
			case 'field':
				//console.log(this.field)
				let field = {};
				field.columnName = xmlNode.getAttribute('name');
				field.columnClassName = xmlNode.getAttribute('class');
				if(xmlNode.getElementsByTagName("fieldDescription")[0]){
					field.description=xmlNode.getElementsByTagName("fieldDescription")[0].innerHTML.replace(/\<\!\[CDATA\[/, '').replace(/\]\]\>/, '');
					if(field.description=="undefined"){
						field.description=""
					}
				}else{
					field.description="";
				}
				this.field.push(field);
				break;
			case 'filterExpression':
				//console.log(this.field)
				let filterexpression =xmlNode.innerHTML.replace(/\<\!\[CDATA\[/, '').replace(/\]\]\>/, '');
					
				this.filterexpression=filterexpression;
				break;
			case 'variable':
				//console.log(xmlNode)
				let Variables = {};
				Variables.text=xmlNode.getAttribute('name').replace(/\ /,"");
				Variables.scope='Variable';
				Variables.resetType=xmlNode.getAttribute('resetType')
				Variables.idOne=parseInt((Math.random()+"").slice(2));

				if(xmlNode.getAttribute('calculation')=="null"){
					Variables.option="Nothing";
				}else{
					Variables.option= xmlNode.getAttribute('calculation');
				}
				if(xmlNode.getAttribute('resetGroup')=="null" || xmlNode.getAttribute('resetGroup')=="undefined" || !xmlNode.getAttribute('resetGroup')){
					Variables.resetGroup="";
				}else{
					Variables.resetGroup= xmlNode.getAttribute('resetGroup');
				}
				Variables.varExpression=xmlNode.getElementsByTagName("variableExpression")[0].innerHTML.replace(/\<\!\[CDATA\[/, '').replace(/\]\]\>/, '');

                

				//Variables.field=xmlNode.getElementsByTagName("variableExpression")[0].innerHTML.replace(/\<\!\[CDATA\[\$F\{/, '').replace(/\}\]\]\>/, '');
				Variables.cls=xmlNode.getAttribute('class');
				this.variable.push(Variables);
				TreeMenu.getInstance().getNum(this.variable.length);
				//console.log(this.variable)
				break;
			case 'parameter':
				let Parameter = {};
				Parameter.text=xmlNode.getAttribute('name').replace(/\ /,"");
				Parameter.scope='Parameter';
				Parameter.idOne=parseInt((Math.random()+"").slice(2));
				Parameter.cls=xmlNode.getAttribute('class');
				this.parameter.push(Parameter);
				TreeMenu.getInstance().getNum2(this.parameter.length);
				break;
				
			default:
				break;
		}
	}

	/**
	 * 是否启动报表默认样式
	 * @return 1：开启 0：不开启
	 */
	isOpenDefaultStyle() {

		for(let i = 0, len = this.chunk.length;i < len;i++) {
			if(this.chunk[i].hasOwnElement()) {
				return 0;
			}
		}

		return 1;
	}
}

ReportPanel.ACTION_NORMAL = 0x00000000;
ReportPanel.ACTION_IN_ELEMENT = 0x00000001;
ReportPanel.ACTION_IN_BASELINE = 0x00000010;
ReportPanel.ACTION_ARCHOR_UPPER_LEFT = 0x00000011;
ReportPanel.ACTION_ARCHOR_UPPER_RIGHT = 0x00000012;
ReportPanel.ACTION_ARCHOR_LOWER_LEFT = 0x00000013;
ReportPanel.ACTION_ARCHOR_LOWER_RIGHT = 0x00000014;

export default ReportPanel;