//vehicle demo script file

//Vehicle control class	
function VehicleController(spmap,listArea)
{
    //This is necessary because IE7 sometimes gets confused about global variables
    if (typeof(spmap)!="undefined")
    {
        this.map=spmap;
        this.layer=this.map.addObjectLayer("Vehicles","vehicleTemplate");
        this.layer.draw();
        this.initialized=true;
    }
    else
    {
        this.moveObjectTimer=setTimeout(associateObjWithEvent(this,"onRetryTimer"),10);
    }

    this.vehicleArray=new Array();
    this.listArea=listArea;
};

VehicleController.prototype.onRetryTimer = function()
{
    if (typeof(map)!="undefined")
    {
        this.map=map;
        this.layer=this.map.addObjectLayer("Vehicles","vehicleTemplate");
        this.layer.draw();
        this.initialized=true;
        createCabs();
    }
    else
    {
        this.moveObjectTimer=setTimeout(associateObjWithEvent(this,"onRetryTimer"),200);
    }  
};
	
VehicleController.prototype.addVehicle = function()
{
    if (!this.initialized)
        return;
        
    var displayName = "Taxi " + (this.vehicleArray.length +1);
        
    var name = "Vehicle " + (this.vehicleArray.length+1);
    
    //TODO: route selection
    var routeRnd = Math.random();
    if (routeRnd>0.7)
    {
        var route = routeCentralGas;
        //newGeoObject.setAttribute("route","Route 1");
    }
    else if (routeRnd>0.3)
    {
        var route = routeScandinavium;
        //newGeoObject.setAttribute("route","Route 2");
    }
    else
    {
        var route = routeTheatreLiseberg;
        //newGeoObject.setAttribute("route","Route 2");        
    }

    var newGeoObject = this.map.createGeoObject(route[0].x,route[0].y,name,"Vehicles","point",null);
    newGeoObject.setAttribute("name",displayName); 
    newGeoObject.activate();

    
    var vehicle = new Vehicle(this.vehicleArray.length, route,newGeoObject,true,this.listArea,displayName);
    this.vehicleArray.push(vehicle);

    //Taxi defaults
    
	var cabEmptyIcon = new Object();
	cabEmptyIcon.image="pic/icon_taxi_4_vacant.png";
	cabEmptyIcon.width=32;
	cabEmptyIcon.height=28;

	var cabEmptySelectedIcon = new Object();
	cabEmptySelectedIcon.image="pic/icon_taxi_4_vacant_select.png";
	cabEmptySelectedIcon.width=36;
	cabEmptySelectedIcon.height=32;
	    
	var cabOccupiedIcon = new Object();
	cabOccupiedIcon.image="pic/icon_taxi_4_occupied.png";
	cabOccupiedIcon.width=32;
	cabOccupiedIcon.height=28;

	var cabOccupiedSelectedIcon = new Object();
	cabOccupiedSelectedIcon.image="pic/icon_taxi_4_occupied_select.png";
	cabOccupiedSelectedIcon.width=36;
	cabOccupiedSelectedIcon.height=32;
	    
    vehicle.vacantIcon=cabEmptyIcon;
    vehicle.occupiedIcon=cabOccupiedIcon;
    vehicle.vacantSelectedIcon=cabEmptySelectedIcon;
    vehicle.occupiedSelectedIcon=cabOccupiedSelectedIcon;
    
    vehicle.setState(false,0,false);
    
    //If this the first object start the update loop
    if (this.vehicleArray.length==1)
    {
        this.moveObjectTimer=setTimeout(associateObjWithEvent(this,"onUpdateTimer"),5);
    }
}

VehicleController.prototype.createCab = function(displayName,route,initialNrOfPassengers,vacantIcon,occupiedIcon,emptySelectedIcon,occupiedSelectedIcon)
{

    var name = "Vehicle " + (this.vehicleArray.length+1);
    var newGeoObject = this.map.createGeoObject(route[0].x,route[0].y,name,"Vehicles","point",null);
    
    newGeoObject.setAttribute("name",displayName);
    newGeoObject.setAttribute("passengers",initialNrOfPassengers);
    
    newGeoObject.activate();
    
    var vehicle = new Vehicle(this.vehicleArray.length, route,newGeoObject,true,this.listArea,displayName);
    vehicle.passengers=initialNrOfPassengers;
    
    vehicle.vacantIcon=vacantIcon;
    vehicle.occupiedIcon=occupiedIcon;
    vehicle.vacantSelectedIcon=emptySelectedIcon;
    vehicle.occupiedSelectedIcon=occupiedSelectedIcon;
        
    this.vehicleArray.push(vehicle);
    
    if (initialNrOfPassengers==0)
        vehicle.setState(false,0,false);
    else
        vehicle.setState(true,vehicle.passengers,false);
    
    //If this the first object start the update loop
    if (this.vehicleArray.length==1)
    {
        this.moveObjectTimer=setTimeout(associateObjWithEvent(this,"onUpdateTimer"),5);
    }
}


VehicleController.prototype.onUpdateTimer = function()
{
    for (var i=0;i<this.vehicleArray.length;i++)
    {
        var isSelected = (follow==this.vehicleArray[i].id)
        this.vehicleArray[i].updatePosition(isSelected);
    }
    
    if (follow!=-1)
    {
        this.map.centerOnGeoObject("Vehicle " + (follow+1),"Vehicles");
        for (var i=0;i<this.vehicleArray.length;i++)
        {
            if (this.vehicleArray[i].id!=follow)
            {
                if (this.vehicleArray[i].entry.style.backgroundColor!="#ffffff")
                    this.vehicleArray[i].entry.style.backgroundColor="#ffffff";
            }
        }
    }
    
    this.updateMagnifyingGlass();
    
    if (!this.layer.isHidden)
        this.layer.refresh();
           

 
    this.moveObjectTimer=setTimeout(associateObjWithEvent(this,"onUpdateTimer"),200);
};

VehicleController.prototype.updateMagnifyingGlass = function()
{
    //Update magnifying glass
    if (this.map.lookingGlass && this.map.lookingGlass.map && this.map.lookingGlass.map.view)
    {
        if (this.map.lookingGlass.map.view.overlayArray.length==0)
        {
            //Draw new layer
            this.lglayer=this.map.lookingGlass.map.addObjectLayer("Vehicles","vehicleTemplate");
            this.lglayer.draw();
            
            for (var i=0;i<this.vehicleArray.length;i++)
            {
                var newObject = this.map.lookingGlass.map.createGeoObject(this.vehicleArray[i].geoObject.point.x,this.vehicleArray[i].geoObject.point.y,this.vehicleArray[i].displayName,"Vehicles","point",null);
                if (this.vehicleArray[i].occupied==false)
                {
                    if (follow==this.vehicleArray[i].id)
                    {
                        newObject.setImage(this.vehicleArray[i].vacantSelectedIcon.image,this.vehicleArray[i].vacantSelectedIcon.width
                                ,this.vehicleArray[i].vacantSelectedIcon.height,""); 
                    }
                    else
                        newObject.setImage(this.vehicleArray[i].vacantIcon.image,this.vehicleArray[i].vacantIcon.width
                                ,this.vehicleArray[i].vacantIcon.height,""); 
                }
                else
                {
                    if (follow==this.vehicleArray[i].id)
                    {
                        newObject.setImage(this.vehicleArray[i].occupiedSelectedIcon.image,this.vehicleArray[i].occupiedSelectedIcon.width
                                ,this.vehicleArray[i].occupiedSelectedIcon.height,"");  
                    }
                    else
                        newObject.setImage(this.vehicleArray[i].occupiedIcon.image,this.vehicleArray[i].occupiedIcon.width
                                ,this.vehicleArray[i].occupiedIcon.height,"");                 
                }
                newObject.setSelectedImage("",null,null,null);
                
                //TODO: Show attributes in magnifying glass?
                //for (var j=0;j<this.vehicleArray[i].geoObject.attributes.length;j++)
                //{
                //    newObject.setAttribute(this.vehicleArray[i].geoObject.attributes[j].name,this.vehicleArray[i].geoObject.attributes[j].value);
                //}
                 
                newObject.activate();       
            }
        }
        else if (this.vehicleArray.length==this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray.length)
        {
            //Only update position
            for (var i=0;i<this.vehicleArray.length;i++)
            {
                this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray[i].setPosition(this.vehicleArray[i].geoObject.point.x,this.vehicleArray[i].geoObject.point.y);
            }
        }
        else
        {
            for (var i=0;i<this.vehicleArray.length;i++)
            {        
                this.map.lookingGlass.map.removeGeoObject(this.vehicleArray[i].displayName,"Vehicles");
            }
            
            for (var i=0;i<this.vehicleArray.length;i++)
            {
                var newObject = this.map.lookingGlass.map.createGeoObject(this.vehicleArray[i].geoObject.point.x,this.vehicleArray[i].geoObject.point.y,this.vehicleArray[i].displayName,"Vehicles","point",null);
                newObject.setSelectedImage("",null,null,null);
                newObject.activate();
            }            
        }
        
        //Set correct icon
        for (var i=0;i<this.vehicleArray.length;i++)
        {
            if (this.vehicleArray[i].occupied==false)
            {
                if (follow==this.vehicleArray[i].id)
                {
                    //TODO: fix hack
                    this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray[i].setImage(this.vehicleArray[i].vacantSelectedIcon.image,this.vehicleArray[i].vacantSelectedIcon.width
                                ,this.vehicleArray[i].vacantSelectedIcon.height,""); 
                }
                else
                    this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray[i].setImage(this.vehicleArray[i].vacantIcon.image,this.vehicleArray[i].vacantIcon.width
                                ,this.vehicleArray[i].vacantIcon.height,""); 
            }
            else
            {
                if (follow==this.vehicleArray[i].id)
                {
                    this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray[i].setImage(this.vehicleArray[i].occupiedSelectedIcon.image,this.vehicleArray[i].occupiedSelectedIcon.width
                                ,this.vehicleArray[i].occupiedSelectedIcon.height,"");  
                }
                else
                    this.map.lookingGlass.map.view.overlayArray[0].geoObjectArray[i].setImage(this.vehicleArray[i].occupiedIcon.image,this.vehicleArray[i].occupiedIcon.width
                                ,this.vehicleArray[i].occupiedIcon.height,"");                 
            }
        }
        
        if (!this.lglayer.isHidden)
            this.lglayer.refresh();
    }
}

function Vehicle(id, routeArray,geoObject,loop, listArea, displayName)
{
    this.route=routeArray;
    this.currentPoint=0;
    this.geoObject=geoObject;
    this.loop=loop;
    this.id=id;
    
    this.displayName=displayName;
    
    //Set speed in m/s
    this.speed=20;
    this.lastUpdate=0;
    
    this.listArea=listArea;
    this.nextDelay=0;
    
    if (this.listArea)
    {
        this.updateListItem();
  
        this.clickDelegate=associateObjWithEvent(this, "onListClick");
	    Evt.addEventListener(this.entry, "click", this.clickDelegate);
    }
   
}

//Update list entry for this vehicle
Vehicle.prototype.updateListItem = function()
{
    if (this.listArea)
    {
        //Remove old item
        if (this.entry)
        {
            this.entry.innerHTML="";
        }
        else
        {
            this.entry = document.createElement("p");
            this.listArea.appendChild(this.entry);
        }
    
        //create new item
        var listImg = document.createElement("img");
        listImg.className="listImage";
        if (this.occupied)
            setImageSource(listImg,"pic/circle_red.png");
        else
            setImageSource(listImg,"pic/circle_green.png");
          
        var listPas = document.createElement("span");  
        if (typeof(this.passengers)!="undefined")
            listPas.innerHTML=this.passengers;
        listPas.className="listPas";
         
        this.entry.innerHTML=this.displayName;
        this.entry.appendChild(listImg);
        this.entry.appendChild(listPas);
       
    }
}

Vehicle.prototype.onListClick = function()
{
    //TODO: fix
    if (follow!=-1)
    {
        vehicleController.vehicleArray[follow].setState(vehicleController.vehicleArray[follow].passengers,
            vehicleController.vehicleArray[follow].passengers,false)
    }
    
    follow = this.id;
    
    this.setState(this.passengers,this.passengers,true)
    this.entry.style.backgroundColor="#ffff30";
}

Vehicle.prototype.updatePosition = function(isSelected)
{
    //Sync speed 
    var newDate=new Date()
    var currentTime=newDate.getTime();
    if (this.lastUpdate>0)
    {
        var speed = this.speed * ((currentTime-this.lastUpdate)/1000);
    }
    else
    {
        var speed=0;
    }

    //If we are supposed to delay, do so here
    if (this.nextDelay>0)
    {
        //TODO: stall here
        this.nextDelay=this.nextDelay - (currentTime-this.lastUpdate);
        this.lastUpdate=currentTime;
        return;
    }
        
    this.lastUpdate=currentTime;
 
     //Calculate distance to next target
    var xDist=this.route[this.currentPoint].x-this.geoObject.point.x; 
    var yDist=this.route[this.currentPoint].y-this.geoObject.point.y;
    var dist = Math.round(Math.sqrt(xDist*xDist + yDist*yDist));
       
    if (dist>0){
        var remainingDist=dist-speed;
        
        if (remainingDist<0){
            this.geoObject.setPosition(this.route[this.currentPoint].x,this.route[this.currentPoint].y);
            this.advanceRoute(isSelected);
        }
        else
        {
            var factor= 1-remainingDist/dist;
            var newX=this.geoObject.point.x + xDist*factor;
            var newY=this.geoObject.point.y + yDist*factor;
            this.geoObject.setPosition(newX,newY,null);
        }
    }
    else
        this.advanceRoute(isSelected);     
}

Vehicle.prototype.advanceRoute = function(isSelected)
{
    if (this.currentPoint<this.route.length-1)
        this.currentPoint++;
    else if (this.loop)
        this.currentPoint=0;
        
    if (this.route[this.currentPoint].delay)
        this.nextDelay=this.route[this.currentPoint].delay;
        
    
    if ( typeof(this.route[this.currentPoint].passengers)!="undefined")
        this.passengers=this.route[this.currentPoint].passengers;
        
    if (this.route[this.currentPoint].setState){
        if (this.route[this.currentPoint].setState=="occupied")
                this.setState(true,this.passengers,isSelected);
        else if (this.route[this.currentPoint].setState=="vacant")
                this.setState(false,this.passengers,isSelected);
    }
}

Vehicle.prototype.setState = function(isOccupied,nrOfPassengers,isSelected)
{
    if (isOccupied)
    {
        if (isSelected)
        {
            this.geoObject.setImage(this.occupiedSelectedIcon.image,this.occupiedSelectedIcon.width
                                ,this.occupiedSelectedIcon.height,"");
        }
        else
            this.geoObject.setImage(this.occupiedIcon.image,this.occupiedIcon.width
                                ,this.occupiedIcon.height,"");
        this.occupied=true;
    }
    else
    {
        if (isSelected)
        {
            this.geoObject.setImage(this.vacantSelectedIcon.image,this.vacantSelectedIcon.width
                                ,this.vacantSelectedIcon.height,""); 
        }
        else
            this.geoObject.setImage(this.vacantIcon.image,this.vacantIcon.width
                                ,this.vacantIcon.height,""); 
        this.occupied=false;   
    }
    
    if ( nrOfPassengers !="undefined"){
        this.passengers=nrOfPassengers;
        this.geoObject.setAttribute("passengers", this.passengers);
    }
    
    if (this.listArea)
    {
        this.updateListItem();
    }
}


