/* */
var ROUTE_DETAILS_MAX_SCALE_LEVEL = 12;

var routeByCounter = 0;
var routeMethod = "Quickest";

var trace_route_from = '';
var trace_route_to = '';
var trace_route_via_cnt = 0;
var trace_route_via = Array(3);
var trace_route_to_hints = Array();
var trace_route_via_hints = Array(3);

var route_details_visible = false;
var route_itenary_data = [];
var route_length;
var route_time;
var route_speed;

var last_route_params;


var routeHintTimeoutHandler;

var route_hint_hide_delayed = undefined;
var last_token='';
function TraceRouteControl() {

    var that = this;
    var locations = new Locations(['from', 'via_1', 'via_2', 'via_3', 'to']);
    var alt_address_controls = new Array();
    var last_route_pois; //struct of last POIs used for finding a new route;
    var _route_last_route;
    var _optimal_bbox = undefined;
    var route_type_control = undefined;
    var last_token = '';
    this.setPanelVisible = function(state, locationFrom, locationShortInfo) {
        if (state==true) {

            eventMapper.setListener('mv-pois.map-center-action',onMapCenter);
            linkHereDB.switchToken(false);
            if (route_details_visible) {
                makeVisible('route_itenary');
                makeVisible('route_header');
                makeVisible('route_footer');
            }
             
            makeVisible('trace_route_form');
            makeVisible('route_options');
            makeInvisible('adverts_placeholder');
            makeVisible('adverts_replacement');  
            
            mvfa.pois_clear("poi-1");
            mvfa.pois_clear("poi-s");
            mvfa.pois_clear("poi-b");
            mvfa.pois_enable('poi-1',false);
            mvfa.pois_enable('poi-s',false);
            mvfa.pois_enable('poi-b',false);

            mvfa.pois_clear("poi-r");
            if (locationFrom!=undefined ){//&& locations['from'].isEmpty() && $('trace_route_from_where').value=='') {
                var temploc = locationFrom.getAddressFull();
                if ((temploc!=undefined) && (temploc.length>0)) {
                    locations['from'].clone(locationFrom);
                    $("trace_route_from_where").value = temploc;
                }
                else 
                    if(locationShortInfo!=undefined && locationShortInfo!=""){
                          $("trace_route_from_where").value = locationShortInfo;
                    }
            }
            var swf_route_points = locations.serializeSWF();
            mvfa.pois_set('poi-r',swf_route_points);
            
            
            if (mvfa.get_scale() > ROUTE_DETAILS_MAX_SCALE_LEVEL) {
                mvfa.pois_set('poi-i',dir_detailed_pois);
            } else {
                mvfa.pois_set('poi-i',dir_pois);
            }
            mvfa.pois_enable('poi-i',true);
            
            SetMenuState(menu_route,true);
            SetMenuState(menu_search,false);
            if (last_route_params != undefined) {
                mvfa.route_on(last_route_params[0], last_route_params[1], last_route_params[2], last_route_params[3],  last_route_params[4]);
            }
        }
    }


    function onMapCenter() {
        if (_optimal_bbox) {
            mvfa.fit_bbox(_optimal_bbox.left,_optimal_bbox.top,_optimal_bbox.right,_optimal_bbox.bottom,0.8);
        }
    }

    this.getLastRoute = function() {
        return _route_last_route;
    }
    function onTraceRouteResponseFromFile(response){
      onTraceRoutePanel();
      onTraceRouteResponse(response);
      linkHereDB.performStep(); 
    }
    this.onTraceRouteResponseFromFile = onTraceRouteResponseFromFile;
    function onTraceRouteResponse(response) {
        
        clearMessage('route_status_messages');
        if (!response.error) {
            _optimal_bbox = response.route_bbox;
//            mvfa.fit_bbox(response.route_bbox.left,response.route_bbox.top,response.route_bbox.right,response.route_bbox.bottom);
            mvfa.route_off();
            linkHereDB.last_route_token = response['link_token'];
            linkHereDB.updatelink(response['link_token']);
            last_route_params = [response.route_id, response.route_bbox.left-2000,response.route_bbox.top+2000,response.route_bbox.right+2000,response.route_bbox.bottom-2000];
            mvfa.route_on(last_route_params[0], last_route_params[1], last_route_params[2], last_route_params[3],  last_route_params[4]);
            routeprintdata = response;
            if (response.route_type == 'Walk') {
                $("route_itenary").innerHTML = response.itenary_body;
                $('route_length').innerHTML = response.total_distance;
                $('route_time').innerHTML = response.total_time;
                $('route_time_desc').innerHTML = "Czas pokonania trasy";
                $('route_avg_speed').innerHTML = "3,6 km/h";
                route_speed = "3,6 km/h";
            }
            else {
                $("route_itenary").innerHTML = response.itenary_body;
                $('route_length').innerHTML = response.total_distance;
                $('route_time').innerHTML = response.total_time;
                $('route_time_desc').innerHTML = "Czas przejazdu";
                $('route_avg_speed').innerHTML = response.average_speed;
                route_speed = response.average_speed;
            }
            route_length = response.total_distance;
            route_time = response.total_time;
            
            makeVisible("route_itenary");
            makeVisible("route_header");
            makeVisible("route_footer");
            onResize();
            route_details_visible = true;
            _route_last_route = response.pois;
            var pointnr = 0;
            for (pname in response.pois) {
                locations[pname].update(response.pois[pname].address);
                
                $('trace_route_'+ pname+'_where').value = locations[pname].getAddressFull();

                alt_address_controls[pname].updateAlternatives(response.pois[pname].alternatives);
            }
            dir_pois = [];
            dir_detailed_pois = [];
            last_multipoint = undefined;
            for (iter in response.itenary) {
                if ((iter>0) && (iter<(response.itenary.length-1))) {
                    
                    imgnr = response.itenary[iter].id;
                    id_nr = imgnr;
                    labelstart = imgnr.replace("_","-");
                    labelstart = labelstart.replace("-0","");
                    
                    
                    big_popup= ['image','/getDirectionMap.php?route='+response.route_id+'&direction='+imgnr,200,200];
                    if(response.itenary[iter].type=="M_MULTIPOINT_END"){
                      id_nr +="_end";
                      big_popup = ['label', labelstart+'. '+response.itenary[iter].label];
                      last_multipoint = "";
                    }
                    if (response.itenary[iter].type == "M_MULTIPOINT") {
                        big_popup = ['label', labelstart + '. ' + response.itenary[iter].label];
                        last_multipoint = imgnr;
                    }
                    else {
                        response.itenary[iter].is_agregate = is_agregate(last_multipoint);
                    }
                    id_mod = id_nr.replace("_0","");
                    dir_pois[iter] = [response.itenary[iter].geometry[0][0],
                                      response.itenary[iter].geometry[0][1],
                                      ""+id_mod,
                                      ['/_gfx/dir/small.png','/_gfx/dir/big.png'],
                                      ['label',labelstart+'. '+response.itenary[iter].label],
                                      big_popup,
                                      "",
                                      response.itenary[iter].type,
                                      response.itenary[iter].is_agregate,
                                      last_multipoint
                                      ];
                    dir_detailed_pois[iter] = [response.itenary[iter].geometry[0][0],
                                               response.itenary[iter].geometry[0][1],
                                               ""+id_mod,
                                               '/_dir/'+imgnr+'.png',
                                               ['label',response.itenary[iter].label],
                                               big_popup,
                                               "",
                                               response.itenary[iter].type,
                                               response.itenary[iter].is_agregate,
                                               last_multipoint
                                               ];
                    
                    if (response.itenary[iter].type != "M_MULTIPOINT_END") {
                        $('route_hint_' + id_mod).onmouseover = partial(onMouseOverRouteHint, "" + id_mod);
                        $('route_hint_' + id_mod).onmouseout = partial(onMouseOutRouteHint, "" + id_mod);
                        $('route_hint_' + id_mod).onclick = partial(function(x, y, z){
                              mvfa.simulate_poi_mouse_click_and_set_coords('poi-i', z, x, y, mvfa.get_scale());
                        }, response.itenary[iter].geometry[0][0], response.itenary[iter].geometry[0][1], "" + id_mod);
                    }
                }
            }
            route_itenary_data = response.itenary;
            mvfa.pois_clear('poi-r');
            var swf_route_points = locations.serializeSWF();
            mvfa.pois_set('poi-r',swf_route_points);
            
            if (linkHereDB.getLinkStep() == 0) {
              mvfa.fit_bbox(response.route_bbox.left, response.route_bbox.top, response.route_bbox.right, response.route_bbox.bottom);
            }
            
            if(linkHereDB.getLinkStep()==0){
                curScale = mvfa.get_scale();
              }else{
                curScale = linkHereDB.getScale(); 
              } 
              if (curScale > ROUTE_DETAILS_MAX_SCALE_LEVEL) {
                mvfa.pois_set('poi-i',dir_detailed_pois);
              } else {
                mvfa.pois_set('poi-i',dir_pois);
              }
            
            
            mvfa.pois_enable('poi-i',true);
            
            return;
        }
        else if (response.error.code == "ADDRESS_NOT_FOUND") {
            if (response.error.poi == 'from') {
                setMessage("Niepoprawny adres w polu Start.",msg_delay, 'route_status_messages');
            }
            else if (response.error.poi == 'to') {
                setMessage("Niepoprawny adres w polu Stop.",msg_delay, 'route_status_messages');
            }
            else {
                setMessage("Nie znaleziono punktu pośredniego nr "+response.error.poi.substring(4)+".",msg_delay,'route_status_messages');
            }
            last_route_params = undefined;
        }
        else if (response.error.code == "ROUTE_NOT_FOUND") {
            setMessage("Nie znaleziono trasy. Sprawdź kryteria wyszukiwania.",msg_delay,'route_status_messages');
            last_route_params = undefined;
        }
        else {
            setMessage(serializeJSON(response.error),msg_delay,'route_status_messages');
            _route_last_route = undefined;
        }
        last_route_params = undefined;
        
        makeInvisible('advert_box');
    }
    this.onTraceRouteResponse = onTraceRouteResponse;
    function onTraceRouteResponseFail(fail_response) {
        
        setMessage("Przepraszamy, błąd połączenia z serwerem. Spróbuj ponownie.",msg_delay,'route_status_messages');
    }
    this.onTraceRouteResponseFail = onTraceRouteResponseFail; 
    function onSubmitTraceRoute(update) {

        makeInvisible('route_itenary');
        makeInvisible('route_header');
        makeInvisible('route_status_messages');
        makeInvisible('route_status_msg_border');
        makeInvisible('route_footer');
        mvfa.pois_clear("poi-s");
        mvfa.pois_clear("poi-i");
        mvfa.route_off();

        $('route_length').innerHTML = "";
        $('route_time').innerHTML = "";
        $('route_avg_speed').innerHTML = "";
        mvfa.pois_clear('poi-r');
        var swf_route_points = locations.serializeSWF();
        mvfa.pois_set('poi-r',swf_route_points);

        
        setMessage("Proszę czekać.",0,'route_status_messages');
        linkHereDB.type= "Zaplanuj swoją trasę"
        if (update!=true) {

            if (strip($('trace_route_from_where').value) == "") {
                setMessage("Wypełnij pole Start.",msg_delay,'route_status_messages');
                return false;
            }
            if (strip($('trace_route_to_where').value) == "") {
                setMessage("Wypełnij pole Stop.",msg_delay,'route_status_messages');
                return false;
            }

            var route_pois = {};
            for (var poi_name_id in locations.locations_keys) {
                var poi_name = locations.locations_keys[poi_name_id];
                poi_where = strip($('trace_route_'+poi_name+'_where').value);
                if (poi_where != "") {
                    if (poi_where == locations[poi_name].getAddressFull()) {
                        route_pois[poi_name] = locations[poi_name].serialize();
                    }
                    else {
                        route_pois[poi_name] = {address_full: poi_where};
                    }
                }
            }
            last_route_pois = route_pois;
        } 
        else if (!route_details_visible) {
            return false; // route not yet selected;
        }
        else {
            route_pois = last_route_pois;
        }

        params = { method: "TraceRoute",
                   type: $('route_type').value,
                   route_pois: serializeJSON(route_pois)};

        if (isIE6()) { params.ie6mode = true; }

        _def = loadJSONDoc(JSON_REQUESTS_PATH,params);
        _def.addCallbacks(onTraceRouteResponse,onTraceRouteResponseFail);
        
        return false;
    }

    function onRouteMarkUpdate(poi_id,type, ref_coords) {
      $('trace_route_submit').focus();
        _def = loadJSONDoc(JSON_REQUESTS_PATH,
                           {method: "GetAddressFromPoint",
                            action: "update",
                            poi_type: 'poi-r',
                            poi_id: poi_id,
                            x92: ref_coords[0],
                            y92: ref_coords[1]
                           });
        _def.addCallbacks(onGetAddressFromPointResponse,onGetAddressFromPointResponseFail);
    }
    this.onRouteMarkStart = partial(onRouteMarkUpdate,'from');
    this.onRouteMarkStop = partial(onRouteMarkUpdate,'to');
    
    function onRouteMarkVia(type, ref_coords) {
        onAddRouteBy();
        $('trace_route_submit').focus();
        _def = loadJSONDoc(JSON_REQUESTS_PATH,
                           {method: "GetAddressFromPoint",
                            action: "update",
                            poi_type: 'poi-r',
                            poi_id: 'via_'+routeByCounter,
                            x92: ref_coords[0],
                            y92: ref_coords[1]
                           });
        _def.addCallbacks(onGetAddressFromPointResponse,onGetAddressFromPointResponseFail);
    }
    this.onRouteMarkVia = onRouteMarkVia;
    
    
    function onRemoveRouteBy(pointname) {
        menu_route.via_remove[2] = false;
        menu_route.via_add[2] = true;
        SetMenuState(menu_route,true);
        
        if (routeByCounter>0) {
            makeInvisible('route_by_nr_'+routeByCounter);

            pointid = parseInt(pointname.substring(4));
            for (var cnt=pointid; cnt<=routeByCounter;cnt++) {
                
                if (cnt<routeByCounter) {
                    locations['via_'+cnt].clone(locations['via_'+(cnt+1)]);
                    $("trace_route_via_"+cnt+'_where').value = locations['via_'+cnt].getAddressFull();
                    alt_address_controls['via_'+cnt].updateAlternatives(alt_address_controls['via_'+(cnt+1)].getAlternatives());
                }
                else {
                    locations['via_'+cnt].update([]);
                    $("trace_route_via_"+cnt+'_where').value = "";
                    alt_address_controls['via_'+cnt].updateAlternatives([]);
                }
            }
            routeByCounter--;
        }
        
        makeInvisible('add_route_by_disabled');
        makeVisible('add_route_by_enabled');
        
        onResize();

        setTimeout(function() {
                mvfa.pois_clear('poi-r');
                var swf_route_points = locations.serializeSWF();
                mvfa.pois_set('poi-r',swf_route_points);
            },10);
        return false;
    }


    function onRouteMarkRemove(type, poi_id) {
        $('trace_route_'+poi_id+'_where').value = "";
        if (poi_id.substring(0,4) =='via_') {
            onRemoveRouteBy(poi_id);
        }
    }
    this.onRouteMarkRemove = onRouteMarkRemove;

    function onRemoveRouteMarkVia() {
        setTimeout(function() {onRemoveRouteBy('via_3')},10);
    }
    this.onRemoveRouteMarkVia = onRemoveRouteMarkVia;

    function onRouteSwitchDirections() {

        var temp = $("trace_route_from_where").value;
        $("trace_route_from_where").value = $("trace_route_to_where").value;
        $("trace_route_to_where").value = temp;
        
        var tloc = new Location();
        tloc.clone(locations['from']);
        locations['from'].clone(locations['to']);
        locations['to'].clone(tloc);

        var talt = alt_address_controls['from'].getAlternatives();
        alt_address_controls['from'].updateAlternatives(alt_address_controls['to'].getAlternatives());
        alt_address_controls['to'].updateAlternatives(talt);
        
        for (var cnt=0;cnt<Math.floor(routeByCounter/2);cnt++) {

            temp = $("trace_route_via_"+(cnt+1)+'_where').value;
            $("trace_route_via_"+(cnt+1)+"_where").value = $("trace_route_via_"+(routeByCounter-cnt)+"_where").value;
            $("trace_route_via_"+(routeByCounter-cnt)+"_where").value = temp;

            tloc.clone(locations['via_'+(cnt+1)]);
            locations['via_'+(cnt+1)].clone(locations['via_'+(routeByCounter-cnt)]);
            locations['via_'+(routeByCounter-cnt)].clone(tloc);

            talt = alt_address_controls['via_'+(cnt+1)].getAlternatives();
            alt_address_controls['via_'+(cnt+1)].updateAlternatives(alt_address_controls['via_'+(routeByCounter-cnt)].getAlternatives());
            alt_address_controls['via_'+(routeByCounter-cnt)].updateAlternatives(talt);
        }

        mvfa.pois_clear('poi-r');
        var swf_route_points = locations.serializeSWF();
        mvfa.pois_set('poi-r',swf_route_points);
        
        return false;
    }

    function locationChanged(name) {
        
    }

    function routeToPointAction(dest_place) {
        onTraceRoutePanel();
        $('trace_route_submit').focus();
        updateLocation(dest_place,'poi-r','to');
        locations.to.setAsForced();
        return false;
    }

    
    this.routeToPointAction = routeToPointAction;
    
    function updateLocation(plocation,ptype,pid) {
        locations[pid].update(plocation);
        $("trace_route_"+pid+"_where").value = locations[pid].getAddressFull();
        var swf_route_points = locations.serializeSWF();
        mvfa.pois_set('poi-r',swf_route_points);
    }

    this.serializeSWF = function() { return locations.serializeSWF() }

    function onRouteTypeChange(ctrlname) {
        //var index = $(ctrlname).selectedIndex;
        var option = $(ctrlname)._src.value;
        routeMethod = option;
        
        if (_route_last_route!=undefined) {
            onSubmitTraceRoute();
        }
    }



    //temporaries
    this.onSubmitTraceRoute = onSubmitTraceRoute;

    /*
     *  real constructor
     */

    /*route_type_control = new DropDown('route_type',
                                      ['najprostsza', 'najkrótsza', 'piesza'],
                                      ['Quickest', 'Shortest', 'Walk'],
                                      '');*/
    $("trace_route_a").onclick = onTraceRoutePanel;
    $("trace_route_submit").onclick = onSubmitTraceRoute;
    $("route_type").onchange = onSubmitTraceRoute;
    $("add_route_by_enabled").onclick = onAddRouteBy;
    //$('route_type').onchange = partial(onRouteTypeChange,'route_type');
    $("route_switch_directions").onclick = onRouteSwitchDirections;
    connect('route_type','route_type_change', onRouteTypeChange);
    
    locations.setSWFmapping('to',-1);
    for (var nameidx in locations.locations_keys) {
        var pname = locations.locations_keys[nameidx];
        alt_address_controls[pname] = new AddressControl(locations[pname],
                                                         'trace_route_'+pname+'_where',
                                                         'trace_route_'+pname+'_alt_addresses_box',
                                                         'trace_route_'+pname+'_alt_addresses',
                                                         'trace_route_'+pname+'_alt_addresses_arrow_img',
                                                         'trace_route_'+pname+'_alt_addresses_arrow');
        
        alt_address_controls[pname].onAddressChange = partial(locationChanged,pname);
        
        LocationHintControl('trace_route_'+pname+'_where',
                            'trace_route_'+pname+'_alt_addresses_box',
                            'trace_route_'+pname+'_alt_addresses');
        
        eventMapper.setListener('mv-pois.update.poi-r.'+pname,updateLocation);
        if (pname.substring(0,4) == 'via_') {
            $('route_by_remove_'+pname).onclick = partial(onRemoveRouteBy,pname);
        }
    }
}


function onAddRouteBy()
{
  if (routeByCounter<3) {
    routeByCounter++;
    
    if (routeByCounter==3) {
      makeInvisible('add_route_by_enabled');
      makeVisible('add_route_by_disabled');
      menu_route.via_remove[2] = true;
      menu_route.via_add[2] = false;
      SetMenuState(menu_route,true);
    }
    
    makeVisible('route_by_nr_'+routeByCounter);
    $('route_by_nr_'+routeByCounter).focus();
    onResize();
  }
  return false;
}


function routeToPointAction(dest_place) {
    
    setTimeout(function () { trace_route.routeToPointAction(new Location(dest_place)); }, 300);
}

function makeRouteHintVisible(control) {
  routeHintTimeoutHandler = setTimeout(partial(function(ctrl) {makeVisible(ctrl); routeHintTimeoutHandler=undefined;},control),1000);
}

function makeRouteHintInvisible(control) {
  if (routeHintTimeoutHandler!=undefined)
    clearTimeout(routeHintTimeoutHandler);
  makeInvisible(control);
}

function onMouseOverRouteHint(x) {
    skip_mvf_change = false;
    if (route_hint_hide_delayed != undefined) {
        if (route_hint_hide_delayed[0] == x) {
            skip_mvf_change = true;
        }
        else {
            mvfa.simulate_poi_mouse_out('poi-i',route_hint_hide_delayed[0]);
        }
        clearTimeout(route_hint_hide_delayed[1]);
    }
    is_mouse_over_simulated = true;
    if (!skip_mvf_change) {
        mvfa.simulate_poi_mouse_over('poi-i',x);
    }
    removeElementClass('route_hint_'+x,'tr_wynik_styl_2');
    addElementClass('route_hint_'+x,'tr_wynik_styl_1');
}

function onMouseOutRouteHint(x) {
    is_mouse_over_simulated = false;
    route_hint_hide_delayed = [x,setTimeout( function() {
                mvfa.simulate_poi_mouse_out('poi-i',x);
                route_hint_hide_delayed = undefined;
            }, 100)];
    removeElementClass('route_hint_'+x,'tr_wynik_styl_1');
    addElementClass('route_hint_'+x,'tr_wynik_styl_2');
    
}

function switch_agregate(id_no){
    element_id="agregate_route_hints_"+id_no;
    img_no = "agregate_state_img_"+id_no;
    if(isVisible($(element_id))){
        makeInvisible($(element_id));
        $(img_no).src = "_dir/down_agregate.png";
        mvfa.switch_agregate_route_pois("poi-i", id_no, false);
    }else{
        makeVisible($(element_id));
        $(img_no).src = "_dir/up_agregate.png";
        mvfa.switch_agregate_route_pois("poi-i", id_no, true);
    }
    //$('trace_route_submit').focus();
};
function is_agregate(id_no){
    var elem = document.getElementById("agregate_route_hints_"+id_no);
    if(elem==null){
      return false;
    }
    if(isVisible($(elem))){
      return false;
    }else{
      return true;
    }
}
