﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference path="VEJS/VeJavaScriptIntellisenseHelper.js" />


Type.registerNamespace("Shoothill.Mapping.ServerControl.Client");


Shoothill.Mapping.ServerControl.Client.MappingClientVEMap = function(element) {
    //Shoothill.Mapping.ServerControl.Client.MappingClientControlClientMethods.initializeBase(this, [element]);
    this._controller = element;
    this._veMap = this._controller.GetMapInstance();
    this.layerHash = new Hashtable();
    this.findResults = new Object();
    this.vePlace - new Object();
}


Shoothill.Mapping.ServerControl.Client.MappingClientVEMap.prototype = {
    initialize: function() {
        Shoothill.Mapping.ServerControl.Client.MappingClientVEMap.callBaseMethod(this, 'initialize');

        // Add custom initialization here  

        this.log('loaded map');

    },

    executeCommands: function(commandDictionary) {
        //debugger;
        for (var i = 0; i < commandDictionary.length; i++) {
            var command = commandDictionary[i].ClientMethod;
            var params = commandDictionary[i].ClientParams;

            //var cmd = "this." + command + "(" + "" + ")";
            //eval(cmd);
            switch (command) {
                case "AddControl":
                    this.AddControl(params);
                    break;
                case "AddShape":
                    this.AddShape(params);
                    break;
                case "AddShapeLayer":
                    this.AddShapeLayer(params);
                    break;
                case "DeleteAllShapeLayers":
                    this.DeleteAllShapeLayers(params);
                    break;
                case "SetZoomLevel":
                    this.SetZoomLevel(params);
                    break;
                case "SetCenterAndZoom":
                    this.SetCenterAndZoom(params);
                    break;
                case "Find":
                    this.Find(params)
                    break;

            }

            switch (command) {
                case "VEShapeLayer_AddShape":
                    this.VEShapeLayer_AddShape(params);
                    break;
            }

        }
    },

    AddControl: function(params) {
        //[0] ElementId
        //[1] zIndex
        this._veMap.AddControl(document.getElementById(params[0]), params[1]);
    },

    AddShape: function(params) {
        //[0] VELatlong
        var shapeType = "Point";
        switch (params[0].GetType) {
            case 0:
                shapeType = "Point";
                break;
            case 1:
                shapeType = "Polyline";
                break;
            case 2:
                shapeType = "Polygon";
                break;
        }

        var shape = new VEShape(shapeType, new VELatLong(params[0].GetPoints[0].Latitude, params[0].GetPoints[0].Longitude));
        this._veMap.AddShape(shape);
    },

    AddShapeLayer: function(params) {
        //[0] Layer ID
        //[1] Index - Should be the same as VE Index
        //[2] Title
        //[3] Description
        var layer;
        layer = this.layerHash.get(params[0]);

        //If layer doesn't exist then create it
        if (layer == null) {
            layer = new VEShapeLayer();
            //Assign GUID to this layer
            layer.ssid = params[0];
            layer.SetTitle = params[2];
            layer.SetDescription = params[3];
            this._veMap.AddShapeLayer(layer);
            this.layerHash.put(params[0], layer);
        }
    },

    DeleteShapeLayer: function(params) {
        var layer;
        layer = this.layerHash.get(params[0]);
        if (layer != null) {
            this._veMap.DeleteShapeLayer(layer);
            this.layerHash.remove(params[0]);
        }
    },

    DeleteAllShapeLayers: function(params) {
        this._veMap.DeleteAllShapeLayers();
        this.layerHash = new Hashtable();
    },

    SetCenterAndZoom: function(params) {
        //[0] LatLong Object
        //[1] ZoomLevel
        this._controller._veMap.SetCenterAndZoom(new VELatLong(params[0].Latitude, params[0].Longitude), params[1]);
    },

    SetZoomLevel: function(params) {
        //[0] ZoomLevel
        this._controller._veMap.SetZoomLevel(params[0]);
    },

    Find: function(params) {
        //[0] What, [1] Where, [2] FindType, [3] ShapeLayer
        //[4] StartIndex, [5] NumberOfResults, [6] ShowResults, [7] CreateResults
        //[8] UseDefaultDisambiguation, [9] setBestMapView, [10] ClientCallback
        var layer;
        debugger;

        layer = this.layerHash.get(params[3]);
        if (layer == null) {
            layer = new VEShapeLayer();
            //Assign GUID to this layer
            layer.ssid = params[3];
            this._controller._veMap.AddShapeLayer(layer);
            this.layerHash.put(params[3], layer);
        }

        if (params[2] == "Default")
            params[2] = "";

        this._controller._veMap.Find(params[0], params[1], null, layer, params[4],
                    params[5], params[6], params[7], params[8], params[9], Function.createDelegate(this, this.findCallback));

        //this._controller._veMap.Find(null, params[1], null, layer);
    },

    findCallback: function(shapeLayer, findResults, places, moreResults, error) {

        this.findResults = findResults;
        this.vePlace = places;
        this._controller.doPostBack(this._controller.createEventArgs('mapFindResultsEvent', this._controller.createDataSet()));
    },

    //*********************VEShapeLayer Functions
    VEShapeLayer_AddShape: function(params) {
        var pointsArray = new Array();
        //TODO: Get the correct instance of the layer and add all the shapes to it
        debugger;
        var layer = this._controller._veMap.GetShapeLayerByIndex(params[0]);
        for (var i = 0; i < params[1][0].GetPoints.length; i++) {
            pointsArray.push(new VELatLong(params[1][0].GetPoints[i].Latitude, params[1][0].GetPoints[i].Longitude));
        }
        var shape = new VEShape(VEShapeType.Pushpin, pointsArray);
    },

    dispose: function() {
        this._veMap = null;

        //Add custom dispose actions here
        Shoothill.Mapping.ServerControl.Client.MappingClientVEMap.callBaseMethod(this, 'dispose');
    }
}


/*******************************************************************************************
* Object: Hashtable
* Description: Implementation of hashtable
* Author: Uzi Refaeli
* Usage: 
* var items = new Hashtable();
* items.put("key1", "value1");
* alert(items.get("key1"));
*******************************************************************************************/

//======================================= Properties ========================================
Hashtable.prototype.hash = null;
Hashtable.prototype.keys = null;
Hashtable.prototype.location = null;

/**
* Hashtable - Constructor
* Create a new Hashtable object.
*/
function Hashtable() {
    this.hash = new Array();
    this.keys = new Array();

    this.location = 0;
}

/**
* put
* Add new key
* param: key - String, key name
* param: value - Object, the object to insert
*/
Hashtable.prototype.put = function(key, value) {
    if (value == null)
        return;

    if (this.hash[key] == null)
        this.keys[this.keys.length] = key;

    this.hash[key] = value;
}

/**
* get
* Return an element
* param: key - String, key name
* Return: object - The requested object
*/
Hashtable.prototype.get = function(key) {
    return this.hash[key];
}

/**
* remove
* Remove an element
* param: key - String, key name
*/
Hashtable.prototype.remove = function(key) {
    for (var i = 0; i < this.keys.length; i++) {
        //did we found our key?
        if (key == this.keys[i]) {
            //remove it from the hash
            this.hash[this.keys[i]] = null;
            //and throw away the key...
            this.keys.splice(i, 1);
            return;
        }
    }
}

/**
* size
* Return: Number of elements in the hashtable
*/
Hashtable.prototype.size = function() {
    return this.keys.length;
}

/**
* populateItems
* Deprecated
*/
Hashtable.prototype.populateItems = function() { }

/**
* next
* Return: true if theres more items
*/
Hashtable.prototype.next = function() {
    if (++this.location < this.keys.length)
        return true;
    else
        return false;
}

/**
* moveFirst
* Move to the first item.
*/
Hashtable.prototype.moveFirst = function() {
    try {
        this.location = -1;
    } catch (e) { /*//do nothing here :-)*/ }
}

/**
* moveLast
* Move to the last item.
*/
Hashtable.prototype.moveLast = function() {
    try {
        this.location = this.keys.length - 1;
    } catch (e) { /*//do nothing here :-)*/ }
}

/**
* getKey
* Return: The value of item in the hash
*/
Hashtable.prototype.getKey = function() {
    try {
        return this.keys[this.location];
    } catch (e) {
        return null;
    }
}

/**
* getValue
* Return: The value of item in the hash
*/
Hashtable.prototype.getValue = function() {
    try {
        return this.hash[this.keys[this.location]];
    } catch (e) {
        return null;
    }
}

/**
* getKey
* Return: The first key contains the given value, or null if not found
*/
Hashtable.prototype.getKeyOfValue = function(value) {
    for (var i = 0; i < this.keys.length; i++)
        if (this.hash[this.keys[i]] == value)
        return this.keys[i]
    return null;
}


/**
* toString
* Returns a string representation of this Hashtable object in the form of a set of entries,
* enclosed in braces and separated by the ASCII characters ", " (comma and space).
* Each entry is rendered as the key, an equals sign =, and the associated element,
* where the toString method is used to convert the key and element to strings.
* Return: a string representation of this hashtable.
*/
Hashtable.prototype.toString = function() {

    try {
        var s = new Array(this.keys.length);
        s[s.length] = "{";

        for (var i = 0; i < this.keys.length; i++) {
            s[s.length] = this.keys[i];
            s[s.length] = "=";
            var v = this.hash[this.keys[i]];
            if (v)
                s[s.length] = v.toString();
            else
                s[s.length] = "null";

            if (i != this.keys.length - 1)
                s[s.length] = ", ";
        }
    } catch (e) {
        //do nothing here :-)
    } finally {
        s[s.length] = "}";
    }

    return s.join("");
}

/**
* add
* Concatanates hashtable to another hashtable.
*/
Hashtable.prototype.add = function(ht) {
    try {
        ht.moveFirst();
        while (ht.next()) {
            var key = ht.getKey();
            //put the new value in both cases (exists or not).
            this.hash[key] = ht.getValue();
            //but if it is a new key also increase the key set
            if (this.get(key) != null) {
                this.keys[this.keys.length] = key;
            }
        }
    } catch (e) {
        //do nothing here :-)
    } finally {
        return this;
    }
};




//Arraylist
function ArrayList() {
    this.aList = []; //initialize with an empty array

}

ArrayList.prototype.Count = function() {
    return this.aList.length;
}

ArrayList.prototype.Add = function(object) {
    //Object are placed at the end of the array

    return this.aList.push(object);
}

ArrayList.prototype.GetAt = function(index) //Index must be a number
{
    if (index > -1 && index < this.aList.length)
        return this.aList[index];
    else
        return undefined; //Out of bound array, return undefined

}

ArrayList.prototype.Clear = function() {
    this.aList = [];
}

ArrayList.prototype.RemoveAt = function(index) // index must be a number
{
    var m_count = this.aList.length;

    if (m_count > 0 && index > -1 && index < this.aList.length) {
        switch (index) {
            case 0:
                this.aList.shift();
                break;
            case m_count - 1:
                this.aList.pop();
                break;
            default:
                var head = this.aList.slice(0, index);
                var tail = this.aList.slice(index + 1);
                this.aList = head.concat(tail);
                break;
        }
    }
}

ArrayList.prototype.Insert = function(object, index) {
    var m_count = this.aList.length;
    var m_returnValue = -1;

    if (index > -1 && index <= m_count) {
        switch (index) {
            case 0:
                this.aList.unshift(object);
                m_returnValue = 0;
                break;
            case m_count:
                this.aList.push(object);
                m_returnValue = m_count;
                break;
            default:
                var head = this.aList.slice(0, index - 1);
                var tail = this.aList.slice(index);
                this.aList = this.aList.concat(tail.unshift(object));
                m_returnValue = index;
                break;
        }
    }

    return m_returnValue;
}

ArrayList.prototype.IndexOf = function(object, startIndex) {
    var m_count = this.aList.length;
    var m_returnValue = -1;

    if (startIndex > -1 && startIndex < m_count) {
        var i = startIndex;

        while (i < m_count) {
            if (this.aList[i] == object) {
                m_returnValue = i;
                break;
            }

            i++;
        }
    }

    return m_returnValue;
}


ArrayList.prototype.LastIndexOf = function(object, startIndex) {
    var m_count = this.aList.length;
    var m_returnValue = -1;

    if (startIndex > -1 && startIndex < m_count) {
        var i = m_count - 1;

        while (i >= startIndex) {
            if (this.aList[i] == object) {
                m_returnValue = i;
                break;
            }

            i--;
        }
    }
    return m_returnValue;
}

ArrayList.prototype.ToArray = function() {
    var array = new Array();
    for (var i = 0; i < this.aList.length; i++) {
        array.push(this.aList[i]);
    }
    return array;
}

ArrayList.prototype.toString = function() {
    return this.aList.ToString();
}

ArrayList.prototype.ToString = function(seperator) {
    return this.aList.ToArray().join(seperator);
}

ArrayList.prototype.Sort = function(comparer) {
    if (comparer) {
        this.aList.sort(comparer);
    }
    else {
        this.aList.sort();
    }
}
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();