﻿function _DrawMan() {
    var DrawMan = Class.create({
        initialize: function(parent, container) {
            this.container = container;
            this.parent = parent;
            this.drawBaseLayer = WSpec.getBaseLayer(29, 'DrawBaseLayer'); //z-index 번호 다시 설정 필요(29는 PoiLayer 밑에 번호임)

            this.drawCircleTileLayer = WSpec.getBaseLayer(29, 'drawCircleTileLayer'); //TileLayer에 붙는 레이어 (타일과 함께 움직임)
            //this.drawCircleBaseLayer = WSpec.getBaseLayer(29, 'drawCircleBaseLayer'); //BaseLayer에 붙는 레이어 (지도 움직여도 이놈은 고정)
            //this.container.appendChild(this.drawCircleBaseLayer);



            this.renderer = null;
            this.level = null; //현재 레벨
            this.width = null; //레이어 넓이
            this.height = null; //레이어 높이
            this.shape = null; //경로이미지개체

            this.drawLeftTop = null;
            this.drawRightBottom = null;

            this.setInnerEvent();

            //this.initDrawMan(WSpec.initlevel); 	//layer 사이즈 설정

            this.polyLine = new Array();
            this.polyLineObject = new Array();

            this.circleObject = new Array();

            //Layer들 TileLayer에 한번만 붙이기 위해(레벨별로 붙일 필요 없음)
            this.AppendPolylineLayer = false;
            this.AppendCircleLayer = false;


        },
        setInnerEvent: function() {
            EventMan.addListener(this.parent, 'zoomTileLayer', this.initDrawMan.bindAsEventListener(this));
            EventMan.addListener(this.parent, 'moveTileLayer', this.moveTileLaverEvent.bindAsEventListener(this));

            /*
            this.container.observe('mousedown', this.mousedown.bindAsEventListener(this));
            this.container.observe('mousemove', this.mousemove.bindAsEventListener(this));
            this.container.observe('mouseup', this.mouseup.bindAsEventListener(this));
            this.drawCircleBaseLayer.observe('mousewheel', this.mousewheel.bindAsEventListener(this));
            this.drawCircleBaseLayer.observe('dblclick', this.dblclick.bindAsEventListener(this));
            this.drawCircleBaseLayer.observe('mouseover', this.mouseover.bindAsEventListener(this));
            this.drawCircleBaseLayer.observe('click', this.click.bindAsEventListener(this));

            if (this.drawCircleBaseLayer.addEventListener) this.drawCircleBaseLayer.observe('DOMMouseScroll', this.mousewheel.bindAsEventListener(this)); //for Mozilla
            */
        },

        //        mousedown: function(event) {
        //            this.drag = true;
        //            EventMan.trigger(this, 'drawman_mousedown', event);
        //        },
        //        mousemove: function(event) {
        //            if (this.drag) {
        //                WSpec.setCursorMove(this.drawCircleBaseLayer);
        //            }
        //            EventMan.trigger(this, 'drawman_mousemove', event);
        //        },
        //        mouseup: function(event) {
        //            if (this.drag) {
        //                this.drag = false;

        //            }
        //            WSpec.setCursorHand(this.drawCircleBaseLayer);
        //            EventMan.trigger(this, 'drawman_mouseup', event);
        //        },
        //        mousewheel: function(event) {
        //            EventMan.trigger(this, 'drawman_mousewheel', event);
        //        },
        //        dblclick: function(event) {
        //            EventMan.trigger(this, 'drawman_dblclick', event);
        //        },
        //        mouseover: function(event) {
        //            WSpec.setCursorHand(this.drawCircleBaseLayer);
        //        },
        //        click: function(event) {
        //            EventMan.trigger(this, 'drawman_click', event);
        //        },


        initDrawMan: function(level) {
            //lon,lat좌표로 pixel구하기 위해서 사전작업 필요
            //			var xtilecount = WSpec.getXTileCount(level);
            //			var ytilecount = WSpec.getYTileCount(level);
            //			
            //			this.width = xtilecount * WSpec.tilesize;
            //			this.height = ytilecount * WSpec.tilesize;
            //			
            //			this.drawBaseLayer.style.width = this.width;
            //			this.drawBaseLayer.style.height = this.height;

            this.level = level;

            //this.layerAppendEvent();

            if (this.polyLine != undefined) {
                //레벨이 바뀌었을 때, 기존 데이터를 지우고 다시 그린다.
                this.requestDraw();
            }

            if (this.circleObject != undefined) {
                this.requestRadiusDraw();
            }
        },
        layerAppendEvent: function() {
            EventMan.trigger(this, 'drawPolyLine', { "level": this.level, "layer": this.drawBaseLayer });
            EventMan.trigger(this, 'drawCircleLayer', { "level": this.level, "layer": this.drawCircleTileLayer });
        },
        moveTileLaverEvent: function() {
            this.drawPolyLine();
            this.requestRadiusDraw();
        },

        getLineStroke: function(r, g, b, a, w) {
            return { r: r, g: g, b: b, a: a, w: w };
        },
        addPolyLines: function(idx, line, stroke) {
            var index = this.polyLine.length;
            this.polyLine[index] = {};
            this.polyLine[index].idx = idx;
            this.polyLine[index].coordList = line.getCoords();
            this.polyLine[index].stroke = stroke;
        },
        delPolyLines: function(index) {
            if (index == undefined) {
                for (var i = 0; i < this.polyLine.length; i++) {
                    this.polyLine[i] = null;
                }
                this.polyLine.length = 0;
                this.removePolyLineLayer();
            }
            else {
                for (var i = 0; i < this.polyLine.length; i++) {
                    if (this.polyLine[i] != null && this.polyLine[i].idx == index) {
                        this.polyLine[i] = null;
                        break;
                    }
                }
            }
        },
        requestDraw: function() {
            if (!this.AppendPolylineLayer) {
                EventMan.trigger(this, 'drawPolyLine', { "level": this.level, "layer": this.drawBaseLayer });
                this.AppendPolylineLayer = true;
            }

            this.removePolyLineLayer();
            this.calPolyLineObject(this.polyLine);
            this.drawPolyLine();
        },

        requestRadiusDraw: function() {
            if (!this.AppendCircleLayer) {
                EventMan.trigger(this, 'drawCircleLayer', { "level": this.level, "layer": this.drawCircleTileLayer });
                this.AppendCircleLayer = true;
            }

            if (this.circleObject[0].coord == "") {
                this.removeCircleLayer();
                for (var i = 0; i < this.circleObject.length; i++) {
                    this.draw2Circle(this.circleObject[i].level, this.circleObject[i].radius, this.circleObject[i].stroke, this.circleObject[i].fill, i);
                    this.setRadiusText(this.circleObject[i].level, this.circleObject[i].radius, i);
                }

            } else {
                var level = this.parent.getMapLevel();
                if (level > 5) return;
                this.removeCircleLayer();
                for (var i = 0; i < this.circleObject.length; i++) {
                    this.drawCircle(this.circleObject[i].coord, this.circleObject[i].radius, this.circleObject[i].stroke, this.circleObject[i].fill);
                }
            }
        },
        drawPolyLine: function() {
            //alert("drawPolyLine");
            if (this.polyLineObject == null || this.polyLineObject.length == 0) {
                return;
            }
            //function 경로 검색 결과 그리기
            bound = this.parent.getBound();
            for (var i = 0; i < this.polyLineObject.length; i++) {
                if (this.polyLineObject[i] == null || this.polyLineObject[i].draw) continue;

                var chkDraw = true;

                if (this.polyLineObject[i].rightBottom.lat > bound[1].lat) chkDraw = false;
                if (chkDraw && this.polyLineObject[i].rightBottom.lon < bound[1].lon) chkDraw = false;
                if (chkDraw && this.polyLineObject[i].leftTop.lat < bound[3].lat) chkDraw = false;
                if (chkDraw && this.polyLineObject[i].leftTop.lon > bound[3].lon) chkDraw = false;

                if (chkDraw) {
                    var lineLayer = WSpec.getBaseLayer(60);

                    lineLayer.setStyle({ left: this.polyLineObject[i].pxLeftTop.x - 10,
                        top: this.polyLineObject[i].pxLeftTop.y - 10,
                        width: Math.abs(this.polyLineObject[i].pxLeftTop.x - this.polyLineObject[i].pxRightBottom.x) + 20,
                        height: Math.abs(this.polyLineObject[i].pxLeftTop.y - this.polyLineObject[i].pxRightBottom.y) + 20
                    });

                    lineLayer = this.drawBaseLayer.appendChild(lineLayer);

                    this.initRenderer(lineLayer);

                    //경로 라인 그리기
                    var shape = new Graphic.Polyline(this.renderer);

                    for (var k = 0; k < this.polyLineObject[i].pxList.length; k++) {
                        if (Prototype.Browser.IE) {
                            this.polyLineObject[i].pxList[k][0] = this.polyLineObject[i].pxList[k][0] - this.polyLineObject[i].pxLeftTop.x + 3;
                            this.polyLineObject[i].pxList[k][1] = this.polyLineObject[i].pxList[k][1] - this.polyLineObject[i].pxLeftTop.y + 9;
                        }
                        else {
                            this.polyLineObject[i].pxList[k][0] = this.polyLineObject[i].pxList[k][0] - this.polyLineObject[i].pxLeftTop.x + 10;
                            this.polyLineObject[i].pxList[k][1] = this.polyLineObject[i].pxList[k][1] - this.polyLineObject[i].pxLeftTop.y + 10;
                        }
                    }

                    shape.addPoints(this.polyLineObject[i].pxList);

                    shape.setStroke(this.polyLineObject[i].stroke);
                    shape.setAntialiasing(true);

                    this.renderer.add(shape);

                    this.polyLineObject[i].draw = true;
                    this.renderer.draw();
                    shape = null;
                }
            }
        },
        initRenderer: function(layer) {
            //function 렌더러 설정
            //append 된 element를 가지고 초기화해야 한다.
            if (Graphic.rendererSupported("VML")) {
                this.renderer = new Graphic.VMLRenderer(layer);
            }
            else if (Graphic.rendererSupported("SVG")) {
                this.renderer = new Graphic.SVGRenderer(layer);
            }
            else if (Graphic.rendererSupported("Canvas")) {
                this.renderer = new Graphic.CanvasRenderer(layer);
            }

            layer = null;
        },
        calPolyLineObject: function(polyLine) {
            if (this.polyLineObject != undefined) {
                for (var i = 0; i < this.polyLineObject.length; i++) {
                    this.polyLineObject[i] = null
                }
                this.polyLineObject.length = 0;
            }

            this.drawLeftTop = null;
            this.drawRightBottom = null;

            for (var i = 0; i < polyLine.length; i++) {
                if (polyLine[i] == null) continue;

                if (this.drawLeftTop == null) {
                    this.drawLeftTop = { "lon": parseInt(polyLine[i].coordList[0].lon), "lat": parseInt(polyLine[i].coordList[0].lat) };
                    this.drawRightBottom = { "lon": parseInt(polyLine[i].coordList[0].lon), "lat": parseInt(polyLine[i].coordList[0].lat) };
                }

                var leftTop = { lon: polyLine[i].coordList[0].lon, lat: polyLine[i].coordList[0].lat };
                var rightBottom = { lon: polyLine[i].coordList[0].lon, lat: polyLine[i].coordList[0].lat };

                var point = WSpec.coordToPixel(leftTop, this.level);

                var pxList = new Array();
                var coordIndex = 0;

                pxList[0] = new Array(2);
                pxList[0][0] = point.x;
                pxList[0][1] = this.height - point.y;

                for (var j = 1; j < polyLine[i].coordList.length; j++) {
                    if (leftTop.lon > polyLine[i].coordList[j].lon) leftTop.lon = polyLine[i].coordList[j].lon;
                    if (leftTop.lat < polyLine[i].coordList[j].lat) leftTop.lat = polyLine[i].coordList[j].lat;

                    if (rightBottom.lon < polyLine[i].coordList[j].lon) rightBottom.lon = polyLine[i].coordList[j].lon;
                    if (rightBottom.lat > polyLine[i].coordList[j].lat) rightBottom.lat = polyLine[i].coordList[j].lat;


                    //전체 영역 좌표를 구한다.
                    if (this.drawLeftTop.lon >= polyLine[i].coordList[j].lon) this.drawLeftTop.lon = polyLine[i].coordList[j].lon;
                    if (this.drawLeftTop.lat <= polyLine[i].coordList[j].lat) this.drawLeftTop.lat = polyLine[i].coordList[j].lat;
                    if (this.drawRightBottom.lon <= polyLine[i].coordList[j].lon) this.drawRightBottom.lon = polyLine[i].coordList[j].lon;
                    if (this.drawRightBottom.lat >= polyLine[i].coordList[j].lat) this.drawRightBottom.lat = polyLine[i].coordList[j].lat;

                    point = WSpec.coordToPixel(polyLine[i].coordList[j], this.level);

                    if (pxList[coordIndex].x != point.x || pxList[coordIndex].y != (this.height - point.y)) {
                        coordIndex++;

                        pxList[coordIndex] = new Array(2);
                        pxList[coordIndex][0] = point.x;
                        pxList[coordIndex][1] = this.height - point.y;
                    }
                }

                this.polyLineObject[i] = {};
                this.polyLineObject[i].draw = false;
                this.polyLineObject[i].leftTop = leftTop;
                this.polyLineObject[i].rightBottom = rightBottom;
                this.polyLineObject[i].pxLeftTop = WSpec.coordToPixel(leftTop, this.level);
                this.polyLineObject[i].pxLeftTop.y = this.height - this.polyLineObject[i].pxLeftTop.y;

                this.polyLineObject[i].pxRightBottom = WSpec.coordToPixel(rightBottom, this.level);
                this.polyLineObject[i].pxRightBottom.y = this.height - this.polyLineObject[i].pxRightBottom.y;

                this.polyLineObject[i].pxList = pxList;
                this.polyLineObject[i].idx = polyLine[i].idx;
                this.polyLineObject[i].stroke = polyLine[i].stroke;

                leftTop = null;
                rightBottom = null;
                point = null;
                pxList = null;
            }
            polyLine = null;
        },
        setDrawCenterAndZoom: function() {
            //좌표와 레벨을 바꾼다.
            var drawCenterCoord = { "lon": this.drawLeftTop.lon + ((this.drawRightBottom.lon - this.drawLeftTop.lon) / 2), "lat": this.drawRightBottom.lat + ((this.drawLeftTop.lat - this.drawRightBottom.lat) / 2) };
            var drawLeftTopPixel = WSpec.coordToPixel(this.drawLeftTop, this.level);
            var drawRightBottomPixel = WSpec.coordToPixel(this.drawRightBottom, this.level);


            var nowWidth = Math.abs(drawRightBottomPixel.x - drawLeftTopPixel.x);
            var nowHeight = Math.abs(drawRightBottomPixel.y - drawLeftTopPixel.y);
            var viewPortWidth = WSpec.viewportwidth;
            var viewPortHeight = WSpec.viewportheight;

            if (nowWidth > nowHeight) {
                if (viewPortWidth > nowWidth) {
                    while (viewPortWidth / 2 >= nowWidth && this.level <= WSpec.maxlevel) {
                        this.level = this.level - 1;
                        viewPortWidth = viewPortWidth / 2;
                    }
                }
                else {
                    do {
                        this.level = this.level + 1;
                        viewPortWidth = viewPortWidth * 2;
                    } while (viewPortWidth <= nowWidth && this.level >= WSpec.minlevel)
                }
            }
            else {
                if (viewPortHeight > nowHeight) {
                    while (viewPortHeight / 2 >= nowHeight && this.level <= WSpec.maxlevel) {
                        this.level = this.level - 1;
                        viewPortHeight = viewPortHeight / 2;
                    }
                }
                else {
                    do {
                        this.level = this.level + 1;
                        viewPortHeight = viewPortHeight * 2;
                    } while (viewPortHeight <= nowHeight && this.level >= WSpec.minlevel)
                }
            }

            if (this.level > WSpec.maxlevel) this.level = WSpec.maxlevel;
            if (this.level < WSpec.minlevel) this.level = WSpec.minlevel;

            EventMan.trigger(this, 'drawPolyLine', { "level": this.level, "layer": this.drawBaseLayer });

            this.parent.setCenterAndZoom(drawCenterCoord, 13 - this.level);

            drawCenterCoord = null;
            drawLeftTopPixel = null;
            drawRightBottomPixel = null;
        },
        removePolyLineLayer: function() {
            for (var i = this.drawBaseLayer.childNodes.length - 1; i >= 0; i--) {
                this.drawBaseLayer.removeChild(this.drawBaseLayer.childNodes[i]);
            }
        },

        //일문지도용.
        drawRadius: function(coord, radius, stroke, fill) {
            this.removeCircleObject();
            this.circleObject[0] = {};
            this.circleObject[0].coord = coord;
            this.circleObject[0].radius = radius;
            this.circleObject[0].stroke = stroke;
            this.circleObject[0].fill = fill;

            this.requestRadiusDraw();
        },

        draw2Radius: function(coord, level, radius1, stroke1, fill1, radius2, stroke2, fill2) {
            this.removeCircleObject();
            this.circleObject[0] = {};
            this.circleObject[0].coord = coord; //""일때는 화면의 중심좌표에 그리기
            this.circleObject[0].radius = radius1;
            this.circleObject[0].stroke = stroke1;
            this.circleObject[0].fill = fill1;
            this.circleObject[0].level = level;

            this.circleObject[1] = {};
            this.circleObject[1].coord = coord;
            this.circleObject[1].radius = radius2;
            this.circleObject[1].stroke = stroke2;
            this.circleObject[1].fill = fill2;
            this.circleObject[1].level = level;

            this.removeCircleLayer();
            for (var i = 0; i < this.circleObject.length; i++) {
                this.draw2Circle(level, this.circleObject[i].radius, this.circleObject[i].stroke, this.circleObject[i].fill, i);
                this.setRadiusText(this.circleObject[i].level, this.circleObject[i].radius, i);
            }
        },


        drawCircle: function(coord, radius, stroke, fill) {
            if (!this.AppendCircleLayer) { //레이어 붙이기
                EventMan.trigger(this, 'drawCircleLayer', { "level": this.level, "layer": this.drawCircleTileLayer });
                this.AppendCircleLayer = true;
            }

            //반경계산
            var level = this.parent.getMapLevel();
            var rad = this.meterToPixel(level, radius);

            //위치 계산
            var point = new WPoint();
            point = WSpec.coordToPixel(coord, level);
            point.y = -point.y;

            this.makeLayerAndCircleDraw(0, point, radius, rad, stroke, fill);
        },
        
        draw2Circle: function(level, radius, stroke, fill, id) {
            if (!this.AppendCircleLayer) { //레이어 붙이기
                EventMan.trigger(this, 'drawCircleLayer', { "level": this.level, "layer": this.drawCircleTileLayer });
                this.AppendCircleLayer = true;
            }

            //반경계산
            var rad = this.meterToPixel(level, radius); //픽셀로 바꾼 반경 (기준레벨의 m을 픽셀로 변경)

            //위치 계산
            var coord = this.parent.getCenter();
            var lvl = this.parent.getMapLevel();
            var point = new WPoint();
            point = WSpec.coordToPixel(coord, lvl);
            point.y = -point.y;

            this.makeLayerAndCircleDraw(id, point, radius, rad, stroke, fill);

        },
        makeLayerAndCircleDraw: function(id, point, radius, rad, stroke, fill) {
            var gap = 6; //테두리 두께를 감안한 넓이를 주기 위해
            var circleLayer = WSpec.getBaseLayer(70);
            circleLayer.setStyle({
                left: point.x - rad - gap / 2,
                top: point.y - rad - gap / 2,
                width: rad * 2 + gap,
                height: rad * 2 + gap
                //background: '#FF0000'
            });
            //circleLayer = this.drawCircleBaseLayer.appendChild(circleLayer);
            circleLayer = this.drawCircleTileLayer.appendChild(circleLayer);
            this.initRenderer(circleLayer);

            //반경그리기
            var circle = null;
            circle = new Graphic.Circle(this.renderer);
            circle.setStroke(stroke);
            circle.setFill(fill);
            circle.setBounds(gap / 2, gap / 2, rad * 2, rad * 2);
            this.renderer.add(circle);
            this.renderer.draw();

            this.setRadiusLayer(radius, point, rad, this.drawCircleTileLayer, id);
        },

        removeCircleLayer: function() {
            /*
            if (this.drawCircleBaseLayer.childNodes.length != 0) {
            for (var i = this.drawCircleBaseLayer.childNodes.length - 1; i >= 0; i--) {
            this.drawCircleBaseLayer.removeChild(this.drawCircleBaseLayer.childNodes[i]);
            }
            }*/
            if (this.drawCircleTileLayer.childNodes.length != 0) {
                for (var i = this.drawCircleTileLayer.childNodes.length - 1; i >= 0; i--) {
                    this.drawCircleTileLayer.removeChild(this.drawCircleTileLayer.childNodes[i]);
                }
            }
        },

        removeCircleObject: function() {
            for (var i = 0; i < this.circleObject.length; i++) {
                this.circleObject[i] = null;
            }
            this.circleObject = null;
            this.circleObject = new Array();
        },

        setRadiusLayer: function(text, point, rad, layer, id) {
            this.RadiusLayer = WSpec.getBaseLayer(80, 'RadiusLayer_' + id);
            this.RadiusLayer.setStyle({
                'color': 'white',
                'fontWeight': 'bold',
                'fontSize': '13px',
                'background': 'black'
            });
            this.RadiusLayer.setOpacity(0.5);
            layer.appendChild(this.RadiusLayer);

            this.RadiusLayer.setStyle({ //이짓을 해줘야 넓이대로 width, height를 잡네.ㅋ(div의 텍스트 들어간 넓이대로)
                width: '',
                height: ''
            });

            var level = this.parent.getMapLevel();
            this.setRadiusText(level, text, id);

            var width_1 = this.RadiusLayer.getWidth();
            var height_1 = this.RadiusLayer.getHeight();

            this.RadiusLayer.setStyle({
                'left': point.x + rad - width_1 / 2,
                'top': point.y - height_1 / 2
            });

            //            this.RadiusLayer.setStyle({
            //                "line-height": '26px'
            //            });
            //this.RadiusLayer.style.lineHeight = (height_1 + 10) + "px"; //이건 vertical-align을 위한 짓. 위에 프로토타입처럼 하면 좋으련만.. 그게 안되서..

        },

        setRadiusText: function(level, radius, id) { //1레벨이 젤 확대 레벨 12레벨이 한반도
            var clevel = this.parent.getMapLevel(); ;
            var currentRad;

            if (clevel > level) currentRad = radius * Math.pow(2, clevel - level);
            else if (clevel < level) currentRad = radius / (Math.pow(2, level - clevel));
            else currentRad = radius;

            var layer = $('RadiusLayer_' + id);

            if (currentRad.toString().length >= 4) currentRad = currentRad / 1000 + "km";
            else currentRad = currentRad + "m";

            //이짓을 해줘야 넓이대로 width, height를 잡네.ㅋ(div의 텍스트 들어간 넓이대로)
            layer.setStyle({
                'width': '',
                'height': ''
            });

            layer.update(currentRad);

            var width_1 = layer.getWidth();
            var height_1 = layer.getHeight();

            layer.setStyle({
                'width': width_1 + 10
            });
        },
        meterToPixel: function(level, rad) {
            var scaleImgPixel = 37; //스케일은 1cm(37픽셀을 기준으로)
            var scale = this.parent.getScale(level); //스케일
            var oneMeterPixel = scaleImgPixel / scale; /*1m당 픽셀*/
            var cRad = rad * oneMeterPixel; //픽셀로 바꾼 반경
            return cRad;
        }

    });
    window.DrawMan = DrawMan;
};
_DrawMan();
