﻿/// <reference path="/js/jquery-1.4.2.js" />
/// <reference path="/js/utils.js" />
/// <reference path="/js/bingmaps-6.3.js" />

var appKey = "AgFTU5C68XLzHszvfZVU6f5J869J96KM1ase9FihYMI_8FbHQBM4IaG3OJohEccU";

function CouponMap(container)
{

    var earthRadius = 6371; // erth radius kilometers

    var shapes = new CList();
    var moveableshapes = new CList();

    var modePositionUniversity = false;
    var positionUniversity = null;

    var dragShape = null;

    function Init() {
        map = new VEMap(container);
        map.SetCredentials(appKey);

        map.AttachEvent("oncredentialserror", function () { alert("invalid map credentials"); });
        
        map.AttachEvent("onmousedown", MouseHandler);
        map.AttachEvent("onmouseup", MouseHandler);
        map.AttachEvent("onmousemove", MouseHandler); 
       
        
        map.LoadMap();
    }

    this.GetMap = function () {
        return map;
    }

    this.GetPositioningObjectLocation = function () {
        if (modePositionUniversity == true || positionUniversity == null)
            return null;
        else {
            return positionUniversity.Location;
        }
    }

    this.SetUniversityPositionMode = function (pu) {
        positionUniversity = pu;

        if (pu.Location.Latitude && pu.Location.Longitude) {
            AddUniversity(pu);
            SetMoveable(pu);
            modePositionUniversity = false;
        } else {
            modePositionUniversity = true;
        }
    }

    this.PlaceUniversity = function (latitude, longitude) {
        if (positionUniversity == null)
            return;

        var o = GetObjectShapeFromData(shapes, positionUniversity);

        if (o == null) {
            modePositionUniversity = false;
            positionUniversity.Location.Latitude = latitude;
            positionUniversity.Location.Longitude = longitude;
            o = AddUniversity(positionUniversity);
            SetMoveable(positionUniversity);
            o.SubmitCoordinates();
        }

        var coors = new VELatLong(latitude, longitude);

        o.GetShape().SetPoints(coors);
        o.SubmitCoordinates();

        map.SetCenterAndZoom(coors, 9);
    }

    this.SetCenter = function (lat, lon) {
        map.SetCenter(new VELatLong(lat, lon));
    }

    this.SetZoomLevel = function (zoom) {
        map.SetZoomLevel(zoom);
    }

    this.DrawCirlce = function (dataobject, radius) {
        var oshape = GetObjectShapeFromData(shapes, dataobject);

        if (oshape == null)
            return;

        oshape.SetAttachedCircle(new Circle(radius));
        
        RedrawAttachedShapes(oshape);
    }

    this.SetMoveable = SetMoveable;

    this.AddUniversity = AddUniversity;

    function SetMoveable(dataobject) {
        var shape = GetObjectShapeFromData(shapes, dataobject);
        if (shape != null)
            moveableshapes.Add(shape);
    }

    function AddUniversity(universityDo) {

        var mapshape = new ObjectShape(universityDo);

        mapshape.GetShape().SetCustomIcon("<img src='/images/map-university.gif' width='30' height='30' />");


        AddObjectShape(mapshape);

        return mapshape;
    }

    function AddObjectShape(shape) {
        shapes.Add(shape);
        map.AddShape(shape.GetShape());
    }

    function MouseHandler(e) {
        if (e.eventName == "onmousedown" && e.elementID != null) {
            var shape = map.GetShapeByID(e.elementID);

            for (var x = 0; x < moveableshapes.Count(); x++) {
                if (moveableshapes.Get(x).GetShape() == shape) {
                    dragShape = moveableshapes.Get(x);
                    return true;
                }
            }

        } else if (e.eventName == "onmouseup") {
            if(dragShape != null)
                dragShape.SubmitCoordinates();
            dragShape = null;
        } else if (e.eventName == "onmousemove" && dragShape != null) {
            var x = e.mapX;
            var y = e.mapY;
            pixel = new VEPixel(x, y);
            var LL = map.PixelToLatLong(pixel);
            dragShape.GetShape().SetPoints(LL);
            RedrawAttachedShapes(dragShape);
            return true; // prevent the default action 
        }

        if (modePositionUniversity == true && e.eventName == "onmousedown") {
            modePositionUniversity = false;
            var ll = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
            positionUniversity.Location.Latitude = ll.Latitude;
            positionUniversity.Location.Longitude = ll.Longitude;
            var obj = AddUniversity(positionUniversity);
            SetMoveable(positionUniversity);
            obj.SubmitCoordinates();
        }
    }

    function RedrawAttachedShapes(dataObject) {
        RemoveAllAttachedShapes(dataObject);
        AddAllAttachedShapes(dataObject);
    }

    function RemoveAllAttachedShapes(objectShape) {
    
        var shapes = objectShape.GetAttachedShapes();

        for (var x = 0; x < shapes.length; x++) {
            objectShape.DetachShape(shapes[x]);
            map.DeleteShape(shapes[x]);
        }
    }

    function AddAllAttachedShapes(objectShape) {

        var circle = objectShape.GetAttachedCircle();

        if (circle != null) {
            AttachCircle(objectShape, circle);
        }
    }

    function AttachCircle(oshape, circle) {
        var lat = (oshape.GetShape().Location.Latitude * Math.PI) / 180; //rad
        var lon = (oshape.GetShape().Location.Longitude * Math.PI) / 180; //rad
        var d = parseFloat(circle.GetRadius()) / earthRadius;  // d = angular distance covered on earth's surface
        var locs = new Array();
        for (x = 0; x <= 360; x++) {
            var p2 = new VELatLong(0, 0)
            brng = x * Math.PI / 180; //rad
            p2.Latitude = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));
            p2.Longitude = ((lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(p2.Latitude))) * 180) / Math.PI;
            p2.Latitude = (p2.Latitude * 180) / Math.PI;
            locs.push(p2);
        }

        circle = new VEShape(VEShapeType.Polygon, locs);
        circle.HideIcon();
        map.AddShape(circle);
        c = circle;
        oshape.AttachShape(circle);
    }

    var c;

    function GetObjectShapeFromData(objectshapes, dataobject) {
        for (var x = 0; x < objectshapes.Count(); x++) {
            if (objectshapes.Get(x).GetDataobject() == dataobject) {
                return objectshapes.Get(x);
            }
        }

        return null;
    }


    Init();
}

function ObjectShape(dataobject) {

    var shape = null;
    var attachedcircle = null;
    var attachedshapes = new CList();
    var dataobject = dataobject;
    var displayAddress = true;
    var displayCoordinates = false;

    function Init() {
        shape = new VEShape(VEShapeType.Pushpin, new VELatLong(dataobject.Location.Latitude, dataobject.Location.Longitude));

        RedrawDescription();
    }

    this.SubmitCoordinates = function () {
        var s = this.GetShape();
        if (s == null)
            return;
        var ll = s.GetPoints();
        if (ll != null && ll.length > 0) {
            dataobject.Location.Latitude = ll[0].Latitude;
            dataobject.Location.Longitude = ll[0].Longitude;
        }
    }

    this.IsAttachedShape = function (s) {
        return attachedshapes.Contains(s);
    }

    this.GetAttachedShapes = function () {
        return attachedshapes;
    }

    this.AttachShape = function (s) {
        attachedshapes.Add(s);
    }

    this.DetachShape = function (s) {
        attachedshapes.Remove(s);
    }

    this.SetAttachedCircle = function (circle) {
        attachedcircle = circle;
    }

    this.GetAttachedCircle = function () {
        return attachedcircle;
    }

    this.GetAttachedShapes = function () {
        return attachedshapes.ToArray();
    }

    this.GetDataobject = function () {
        return dataobject;
    }

    this.GetShape = function () {
        return shape;
    }

    this.SetDisplayAddress = function (display) {
        displayAddress = display;

        RedrawDescription();
    }

    this.SetDisplayCoordinates = function (display) {
        displayCorr = display;

        RedrawDescription();
    }


    function RedrawDescription() {
        var description = "";

        description += "<h1>title 1</h1>";


        description += "<h2>title 2</h2>";
        if (displayAddress) {
            description += "<div>";
            description += "<h3>Address</h3>";

            description += dataobject.Street + " " + dataobject.HouseNumber + "<br />";
            description += dataobject.PostalCode + " " + dataobject.City;

        }
        

        //shape.SetDescription(description);
    }

    Init();
}

function Circle(radius) {
    var radius = radius;

    this.SetRadius = function (r) {
        radius = r;
    }

    this.GetRadius = function () {
        return radius;
    }
}
