﻿/*
VMShapeCollection class
Author: Hung Duong
Description: to plot a collection of points on the map.
*/
document.write("<script type='text/javascript' src='JavaScript/InfoBox.js'></script>");
function makeIcon(iconURL, iconSize){
    
    if (!isIE6OrLower()){
        return iconURL;
    }
    var img = document.createElement("img");
    img.src = iconURL;
    var h = img.height;
    var w = img.width;
    var div = "<div style=\"width:" +w+ "px; height:" +h+ "px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',src='" + iconURL + "', , sizingMethod='crop');\"></div>";
    
    return div;
}


// Collection of shapes created by parsing the xml data downloaded a table from the server.
//(shape of the same type. e.g: customer, address, ect..)
//Used mainly for pin clickable points
function VMShapeCollection (theMap){    
    
    var xmlFeedURL;   //the url of the xml feed that contains the data for the whole collection
    var shapes = new Array();   //store the actual shape objects
    var shapesLayer = new VEShapeLayer();  //the layer where the shapes will be stored
    
    var bound;
    var map = theMap;
    var current;
    var cnt = 0;
    var interval = 10;
    var zoomTo = null;
    
    this.setXmlFeedSoure = setXmlFeedSoure;
    this.setZoomToBound = setZoomToBound;
    this.getBound = getBound;
    this.setShapes = setShapes;
    this.getShapes = getShapes;
    this.zoomToBound = zoomToBound;
    this.drawShapes = drawShapes;
    this.addShape = addShape;
    this.addPoint = addPoint;
    this.deleteShapes = deleteShapes;
    this.importPinsFromDB = importPinsFromDB;
    this.isEmpty = isEmpty;
    this.isDisplayColName = isDisplayColName;
    this.onlyOnePoint = onlyOnePoint;
    
    var max_lat = -999;
    var min_lng = 999;
    var min_lat = 999;
    var max_lng = -999;
    
    var themeColName;   //the name of column where the theming will be based on
    var displayColNames;  //name of columns that will be displayed in the info box
    var iconType;      //RANDOM, CUSTOM, "SQUARE", "TRIANGLE", "PLUS", "CIRCLE", "FLAG", "PIN", "DIAMOND"                       
    var sameIcon;     //all shapes in the collection will has the same icon                                           
    var title;        //title in the info box              
    
    //get and set methods    
    function isEmpty(){
        return (shapes.length ==0);
    }
    function setXmlFeedSoure (url){
        xmlFeedURL = url;
    }
    function setZoomToBound(b){
        zoomTo = b;
    }
    
    function getXmlFeedSoure (){
        return xmlFeedURL;
    }
    function getBound (){
        bound = new Array(
			              new VELatLong(max_lat, min_lng),
			              new VELatLong(min_lat, max_lng)
			            );
	   return bound;
    }
    function addShape( shape){
        shapes.AddShape(shape);
    }
    function getShapes(){
        return shapes;
    }
    //add a point to the collection
    function addPoint (lat, lng, title, description, iconURL){
        
        var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(lat, lng));
        
        shape.SetTitle(title);
        
        shape.SetDescription(description);
        
        shape.SetCustomIcon(makeIcon(iconURL, 12)); 
        
        shapes[cnt] = shape;
        
        //update count
        cnt++;
        //update minimum bound
        if (lat > max_lat) {
            max_lat = lat;
        }                
        if (lat < min_lat) {
            min_lat = lat;
        }
        if (lng > max_lng) {
            max_lng = lng;
        }
        if (lng < min_lng) {
            min_lng = lng;
        }
        
        
    }
    //create a point obj
    function makePointObj (lat, lng, title, description, iconURL){
        
        var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(lat, lng));
        
        shape.SetTitle(title);
        
        shape.SetDescription(description);
        
        shape.SetCustomIcon(makeIcon(iconURL, 12)); 
        
        shapes[cnt] = shape;
        
        cnt++;
        
        if (lat > max_lat) {
            max_lat = lat;
        }                
        if (lat < min_lat) {
            min_lat = lat;
        }
        if (lng > max_lng) {
            max_lng = lng;
        }
        if (lng < min_lng) {
            min_lng = lng;
        }
        return shape;
        
    }
    function deleteShapeByIndex(index){
        try {
            map.DeleteShape(shapes[index]);
        }catch (ex){
        }
    }
    function setShapes(theShapes){
        shapes = theShapes;
    }
    //zoom map to the minumum bound of the collection
    function zoomToBound(theMap){
        if (isEmpty()){
            return;
        }
        map = theMap;        
        map.SetMapView(getBound());
        if (onlyOnePoint() == true){         
            map.SetZoomLevel(14);
        }
    }
    //check if the collection contain only 1 point, used for zoom to bound
    function onlyOnePoint(){
        return (shapes.length == 1);
    }
    //draw the shapes on the map
    function drawShapes(){
       
        if (isEmpty()){
            return;
        }
        
        cnt = shapes.length;
        current = 0;
        
        if (cnt == 0){
            alert ("Shape collection is empty. Nothing was added to the map");
            return;
        }
        
        map.AddShapeLayer(shapesLayer);
        //zoom to the bound of collection first
        //zoomToBound(map);
        //addShapesToMapRecur();
        
        addShapesToMap();
        
    }
    
    function addShapesToMap(){
        
        for (var i = 0; i < shapes.length; i++){          
                //add shapes to the layer
                var shape = shapes[i];
                shapesLayer.AddShape(shape);
                //set the infobox (add the clear and close links)
                shape.SetDescription(shape.GetDescription() + "<br><a href='javascript:deleteShapeById(\"" + shape.GetID() + "\")'>Clear</a>");               
                
                //map.AddShape(shapes[current]);                
        }
        hideMsgBox();
        
    }
    //recursively add shapes using windows set time out so that the user see the progress for adding point
    //if adding a lot of points then user has to wait for a long time before seing all the points.
    function addShapesToMapRecur(){
        //have to set this so the recursive call is defined
        this.addShapesToMapRecur = addShapesToMapRecur;
        //current is the counter to terminate
        if (current < cnt){
            var max=Math.min(current+ interval,cnt);
            while (current < max){               
                
                var shape = shapes[current];
                shapesLayer.AddShape(shape);
                
                shape.SetDescription(shape.GetDescription() + "<br><a href='javascript:deleteShapeById(\"" + shape.GetID() + "\")'>Clear</a>");
                //map.AddShape(shapes[current]);
                current++;
            }
            window.setTimeout("addShapesToMapRecur();", 10);
        }else {
            //alert (cnt + " item(s) added to the map");
            hideMsgBox();
        }
    }
    //recusively delete the shapes from the map
    function deleteShapesToMapRecur(){
        this.deleteShapesToMapRecur = deleteShapesToMapRecur;
        if (current < cnt){
            var max=Math.min(current+ interval,cnt);
            while (current < max){
                map.DeleteShape(shapes[current]);
                current++;
                //alert (current);
            }
            window.setTimeout("deleteShapesToMapRecur();");
        }else {
            //alert (cnt + " item(s) added to the map");
        }
    }
    function deleteShapes(){
        try {
            map.DeleteShapeLayer(shapesLayer);            
            return;
        } catch (ex){
        
        }
        /*
        if (shapes){
            cnt = shapes.length;
            current = 0;            
            if (cnt != 0){
                
                deleteShapesToMapRecur();                 
                //shapes = new Array();
                return;
            }
        }
        */
        
        
    }
    //import pins from the database using sql clause
    //the sqlclause must alway include lat,lng in select statement
    //iconSoure = "Random" or "Static"
    //if iconSoure = "Random", the iconPath is form by the VMRandomIcon.ashx, themeValue will be used 
    //if iconSoure = "Static", the iconPath is form by this formula "Title_themeValue.png"
    //theDisplayColNames: array of col names that will be displayed in the info box of the pushin            
    function importPinsFromDB(sqlClause, theTitle, theThemeColName, theDisplayColNames,theIconType, theSameIcon){ 
        //deleteShapes();
        //alert ('clause in coll: ' + "AspNet/VMXml.ashx?sqlClause="+sqlClause);   
        try {            
        shapesLayer = new VEShapeLayer();
        
        title = theTitle;
        iconType = theIconType;
        sameIcon = theSameIcon;
        
        themeColName = theThemeColName;
        displayColNames = theDisplayColNames;
        
        var xmlDownload = new XmlDownload();
        
        //alert ('clause in coll: ' + "AspNet/VMXml.ashx?sqlClause="+sqlClause);
        xmlDownload.loadXmlDoc("AspNet/VMXml.ashx?sqlClause="+sqlClause, parseXmlToPins);
        window.setTimeout("displayMsgBox('Processing, please wait .....');");
        } catch (ex){
            alert (ex.message);
        }
        
    }
    //check if a column is in the display list
    function isDisplayColName(colName){
        if (!displayColNames){
            return false;
        }
        
        for (var i = 0; i < displayColNames.length; i++){
            if (displayColNames[i].toLowerCase() == colName.toLowerCase()){                
                return true;
            }
        }
        return false;
    }
    
    //Parse the xml document to and create pushin
    function parseXmlToPins(docElement){
        try {
        var rowSet = docElement.getElementsByTagName("ROW");        
        var iconPathFactory = new IconPathFactory();
        //alert (rowSet.length);
        for (var i = 0; i < rowSet.length; i++){
            var row = rowSet[i];
            var lat;
            var lng;
            var themeValue= "";
            var iconURL;
            var infoBox = new InfoBox();
            infoBox.setTitle(title);
            
            //alert ("chidl of row lenght:" + row.childNodes.length);
            //alert ("row " + i);
            for (var j = 0; j < row.childNodes.length; j++){                
                var col = row.childNodes[j];
                
                //this is for skipping the white space in firefox
                if (col != null && col.nodeType == 1){                       
                    var colName = col.nodeName;
                    
                    var colVal = "";
                    if (col.hasChildNodes()) {
                        colVal = col.firstChild.nodeValue;
                        //alert ("colval:" + colVal);
                    }                    
                    
                    if (equalIgnoreCase(colName,"LAT")){
                        //convert string to number
                        lat = colVal-0;
                        //alert (lat);
                    }
                    if (equalIgnoreCase(colName,"LNG")){
                        //convert string to number
                        lng = colVal-0;
                        //alert (lng);
                    }
                    if (equalIgnoreCase(colName,themeColName)){
                        //convert string to number
                        themeValue = colVal;
                        //alert (themeValue);
                    }
                    var isDisplay = isDisplayColName(colName);
                    if (isDisplay){
                        infoBox.addDescription(colName, colVal);
                    }
                    //alert (isDisplay);
                    
                }
            }
            if (iconType == "CUSTOM" ){
                /*
                var ext = ".png";
                if (sameIcon == true){
                    iconURL = iconPathFactory.getPath(iconType, title + ext);
                }else {
                    iconURL = iconPathFactory.getPath(iconType, themeValue+ext);
                }
                */
                iconURL = iconPathFactory.getPath(iconType, themeValue);
                
            }else {
                iconURL = iconPathFactory.getPath(iconType, themeValue);
            }
            
            var shape = makePointObj (lat, lng, infoBox.getTitle(), infoBox.getDescription(), iconURL);
            shapesLayer.AddShape(shape);
                
            shape.SetDescription(shape.GetDescription() + "<br><a href='javascript:deleteShapeById(\"" + shape.GetID() + "\")'>Clear</a>");
                
                
            //map.AddShape(shapes[current]);       
            
        }
        //alert ("endparse");
        if (zoomTo == true){
            zoomToBound(map);
        }
        drawShapes();
        
        } catch (ex){
            hideMsgBox();
        }
        hideMsgBox();
        
    }        
    
}


