/**
 * create Cinema in SAPO.namespace
 */ 
if(!SAPO.Cinema || typeof(SAPO.Cinema) == 'undefined') {
    SAPO.namespace('Cinema');
}


/**
 * Sapo.Cinema.movieScheduleFilters constructor
 */
SAPO.Cinema.movieScheduleFilters = function(options)
{
    this.init(options);
};


/**
 * Sapo.Cinema.movieScheduleFilters methods
 */
SAPO.Cinema.movieScheduleFilters.prototype = {       

    appUrl : '',
    loadingCombos : [],
    ignoreErrors : true,
    
    /*Sapo Maps*/
    map : null,
    mapPlace : null,
    polygon : null,

    /**
     * init
     */    
    init: function(args) 
    {
        //configure       
        if (args.appUrl) { 
            this.appUrl = args.appUrl;
        }          
        
       if(args.mapPlace)
            this.mapPlace = args.mapPlace;

        /*if(this.mapPlace)
            this.map = new SAPO.Maps.Map( args.mapPlace );*/
        //alert(this.map);
        
        
        this.enhanceSearch();
    },   

    

    /**
     * enhance search buttons
     */    
    enhanceSearch: function() 
    {
        // change district
        if ($('district')) {
            $('district').observe('change', this.changeDistrict.bindAsEventListener(this));
        }
        // change council
        if ($('council')) {            
            $('council').observe('change', this.changeCouncil.bindAsEventListener(this));
        }
        // chance cinema
        if ($('cinema')) {            
            $('cinema').observe('change', this.changeCinema.bindAsEventListener(this));   
        }
        // change movie
        if ($('movie')) {            
            $('movie').observe('change', this.changeMovie.bindAsEventListener(this));   
        }
        // auto submit list options 
        $$('.listModeOptions input').each( function(el) {
            el.observe('click', function (ev) {
                ev.target.form.submit();
            } );
        } ); 
        // ignore ajax errors after submit
        $('scheduleFilters').observe('submit', function(ev) { this.ignoreErrors = true }.bind(this) );                
    },    
    
    
    
    /**
     * change district
     */
    changeDistrict: function() 
    {
        //alert('#districtChange');
        this.districtSlug = $('district').value;
        this.councilSlug = this.comboClear('council');      
        this.cinemaSlug = ($('cinema')) ? this.comboClear('cinema') : 0;        
        this.movieSlug = ($('movie')) ? this.comboClear('movie') : 0;                                         
        
        this.resetLocation();
        
        // update councils?
        if (this.districtSlug != 0)
        {
            this.updateCouncil();    
        }   
        // no, update cinemas and movies       
        else
        {
            this.comboFirstOption('council', ' -- todos os concelhos -- ');
            this.councilSlug = 0;
            if ($('cinema')) {
                this.updateCinema();
                if ($('movie')) {
                    this.updateMovie(); 
                }
            }
        }
    },


    /**
     * update council
     */
    updateCouncil: function() 
    {
        this.comboLoading('council');

        var url = this.appUrl + '/ajax-get-council.php';
        var params = { 'districtSlug' : this.districtSlug };
        this.ajaxRequest(url, params, function (response) { this.updateCouncilCallback(response) }.bind(this));    
    },
    
    /**
     * findCinemasByMyLocation
     */
    findCinemasByMyLocation: function() 
    {
        this.comboLoading('council');

        var url = this.appUrl + '/ajax-get-council.php';
        var params = { 'districtSlug' : this.districtSlug };
        this.ajaxRequest(url, params, function (response) { this.updateCouncilCallback(response) }.bind(this));    
    },
    
    /**
     * response handler for council 
     */
    updateCouncilCallback: function(response)
    { 
        //alert('####### council callback = ' + response.items.length);
        this.comboClear('council');    
        this.comboFirstOption('council', ' -- todos os concelhos -- ');
        // fill in councils              
        var found = false;
        for (var i = 0; i < response.items.length; i++)
        {
            var newOption = document.createElement('option');   
            newOption.text = response.items[i].councilName;
            newOption.value = response.items[i].councilSlug;         
            if (response.items[i].councilSlug == this.councilSlug) 
            {   
                newOption.defaultSelected = true;
                found = true; 
	        }                         
            $('council').options.add(newOption);
        }  
        // reset council?            
        if (!found) this.councilSlug = 0;
        // cascade update cinema
        if ($('cinema')) { 
            this.updateCinema();
        }
    },   
     
    
    /**
     * change council
     */
    changeCouncil: function() 
    {
        //alert('#councilChange');
        this.districtSlug = $('district').value;
        this.councilSlug = $('council').value;
        this.cinemaSlug = ($('cinema')) ? this.comboClear('cinema') : 0;
        this.movieSlug = ($('movie')) ? this.comboClear('movie') : 0;
        
        this.resetLocation();
        
        // update cinemas and movies
        if ($('cinema')) {
            this.updateCinema();
        }
    },
    
    
    /**
     * update cinema
     */
    updateCinema: function(lat, lon, radius) 
    {
        this.comboLoading('cinema');
        var url = this.appUrl + '/ajax-get-scheduleCinema.php';
        if(!this.districtSlug || !this.councilSlug){
            this.districtSlug = $('district').value;
            this.councilSlug = $('council').value;
        }
        var params = { 'districtSlug' : this.districtSlug, 'councilSlug' : this.councilSlug };
        params.latitude = $('latitude').value;
        params.longitude = $('longitude').value;
        params.radius = $('radius').value;
        this.removeCircle();
        this.ajaxRequest(url, params, function (response) { this.updateCinemaCallback(response) }.bind(this));
    },
    
    
    /**
     * response handler for cinema 
     */
    updateCinemaCallback: function(response)
    { 
        
        if ($('cinema')) {
            this.comboClear('cinema');
            
            // there are any cinmeas to display?
            if (response.items.length){
                this.comboFirstOption('cinema', ' -- todos os cinemas -- ');
                // fill in cinemas              
                var found = false;
                for (var i = 0; i < response.items.length; i++)
                {
                    var newOption = document.createElement('option');   
                    newOption.text = response.items[i].entityName;
                    newOption.value = response.items[i].entitySlug;    
                    if (response.items[i].entitySlug == this.cinemaSlug) {
                        newOption.defaultSelected = true;
                        found = true;
                    }                                                  
                    $('cinema').options.add(newOption);
                }
                
                this.cacheCinemas = response;
                this.addsMarkers();
                
                // reset cinema
                if (!found) this.cinemaSlug = 0;
                // cascade update movie
                this.updateMovie();
                
            }
            // empty result set
            else {
                this.comboFirstOption('cinema', 'nenhum cinema encontrado');
                this.comboFirstOption('movie', 'nenhum filme encontrado');
            }            
        }
    },       
    
    /**
     * change cinema
     */
    changeCinema: function()
    {
        //alert('#cinemaChange');
        this.districtSlug = $('district').value;
        this.councilSlug = $('council').value;
        this.cinemaSlug = ($('cinema')) ? $('cinema').value : 0;
        this.movieSlug = ($('movie')) ? this.comboClear('movie') : 0;                   
        // update movies                    
        if ($('movie')) {         
            this.updateMovie();
        }        
    },     
    
        
    /**
     * change movie
     */
    changeMovie: function()
    {
        // reset cinema?
        if ($('movie').value) 
        {
        	if ($('cinema')) {
        		$('cinema').selectedIndex = 0;
        	}	
        		
        }
        	
    },     
    
    
    /**
     * update movie
     */
    updateMovie: function() 
    {
        this.comboLoading('movie');
            
        var url = this.appUrl + '/ajax-get-scheduleMovie.php';
        var params = { 'districtSlug' : this.districtSlug, 'councilSlug' : this.councilSlug, 'cinemaSlug' : this.cinemaSlug};
        if(this.cacheCinemas && this.cacheCinemas.latitude){
            params.latitude = this.cacheCinemas.latitude;
        }
        if(this.cacheCinemas && this.cacheCinemas.longitude){
            params.longitude = this.cacheCinemas.longitude;
        }
        if(this.cacheCinemas && this.cacheCinemas.radius){
            params.radius = this.cacheCinemas.radius;
        }
        this.ajaxRequest(url, params, function (response) { this.updateMovieCallback(response) }.bind(this));
    }, 
    
    
    /**
     * response handler for cinema 
     */
    updateMovieCallback: function(response)
    { 
        if ($('movie')) {     
            //alert('####### movie callback = ' + response.items.length);
            this.comboClear('movie');
            // there are movies to display?
            if (response.items.length) {
                this.comboFirstOption('movie', ' -- todos os filmes -- ');    
                // fill in movies           
                for (var i = 0; i < response.items.length; i++)
                {
                    var newOption = document.createElement('option');
                    if (response.items[i].title)
                    {
                        newOption.text = response.items[i].title;
                    }
                    else
                    {
                        newOption.text = response.items[i].originalTitle;
                    }
                    newOption.value = response.items[i].workSlug; 
                    if (response.items[i].workSlug == this.movieSlug) newOption.defaultSelected = true;
                    $('movie').options.add(newOption);
                }      
            }
            // empty result set
            else {
                this.comboFirstOption('movie', 'nenhum filme encontrado');
            }
        }
    },    
    
    
    /**
     * handle ajax request
     *
     * TODO MOVE TO object.js
     *
     * @param whatever data
     */
    ajaxRequest : function(url, params, successCallback) 
    {
        // send request
        new Ajax.Request(url, {
            parameters: params,                       
            onCreate: function(request) { this.ajaxConnection = request; }.bind(this),
            onFailure: function(foo) { this.ajaxError('Ups!', foo); }.bind(this),
            onException: function(foo, e) { this.ajaxError('Hum...', e); }.bind(this), 
            onSuccess: function(data) {
                // check valid JSON              
                try
                {
                    if (!data.responseText.isJSON()) throw "!"; 
                    var response = data.responseText.evalJSON(true);
                    if (typeof(response) != 'object') throw "!";
                    try                
                    {
                        // callback
                        if (typeof(successCallback) == 'function') successCallback(response);
                    }
                    catch(e)
                    {               
                        return this.ajaxError('Ouch!', e);
                    }                
                }
                catch(e)
                {               
                    return this.ajaxError('Duh!', data.responseText.replace(/(<([^>]+)>)/ig,"").substr(0, 300));
                }                
            }.bind(this)
        } );               
    },    
    
    
    /**
     * handle ajax error
     *
     * left for breakpoint debugging
     *
     * @param whatever data
     */
    ajaxError : function(title, text)
    {          
        if (!this.ignoreErrors) { 
            this.dialogShow(title, text, false); }
    },        
    
    
    /**
     * show dialog
     *
     * @param string title
     * @param string text
     * @param boolean ok
     */
    dialogShow : function(title, text, ok)
    {                
    },


    /**
     * clears combo and returns the value of the previously selected item
     *
     * @param string element id
     * @return mixed value of previously selected item
     */
    comboClear: function (id) 
    {
        // validate        
        if ($(id) && $(id).options) {
            //           
            var oldValue = $(id).value;
            // clear     
            for (i = $(id).options.length-1; i >= 0; i--) {
                $(id).options[i]=null;
            }
            return oldValue;
        }
    },

    
    /**
     * adds a "loading" placeholder option
     *
     * @param string element id
     */
    comboLoading: function(id) 
    {
        // validate        
        if ($(id) && $(id).options) {
            var newOption = document.createElement('option');   
            newOption.text = '...a carregar....';
            newOption.value = 0;
            newOption.defaultSelected = true;
            $(id).options.add(newOption);
        }
    },   
    
    
    /**
     * adds a "choose" placeholder option
     *
     * @param string element id
     */
    comboFirstOption: function(id, text)
    {
        // validate        
        if ($(id) && $(id).options) {
            var newOption = document.createElement('option');   
            newOption.text = text;
            newOption.value = 0;
            $(id).options.add(newOption);
        }
    },


    /*
        Styles Object
    */
    markerStyle: {
        markerImage  : 'http://imgs.sapo.pt/cinema/media/cinema/nav/iconMarker20.gif',
        /*markerAnchor : new OpenLayers.Pixel(-10,-10),*/
        size : new OpenLayers.Size(20, 20)
    },
    invalidMarkerStyle: {
        markerImage  : 'http://imgs.sapo.pt/cinema/media/cinema/nav/iconMarkerInvalid20.gif',
        markerAnchor : new OpenLayers.Pixel(-10,-10),
        size : new OpenLayers.Size(20, 20)
    },
    /*
        toggle place map
     */
    toggleMap: function(place, targetElement){
        if( this.map==null ){
            this.createMap();
            this.updateCinema();
        }
        if($(place).style.display=='none'){
            $('mapDivLnk').addClassName('active');
            $(place).show();
        }else{
            $('mapDivLnk').removeClassName('active');
            $(place).hide();
        }
    },
    /*
        Create map
     */
    createMap: function(){
        this.map = new SAPO.Maps.Map(this.mapPlace);
        this.map.zoomTo(7);
        this.map.disableScrollWheelZoom();
    },
    /*
        Move map to lat/lon, if has radius create circle and set zoom from bounds
     */
    centerMap: function(lon,lat,radius){
        try{
            this.map.setMapCenter(new OpenLayers.LonLat(Number(lon),Number(lat)));
            //context point
            if(radius){
                this.removeCircle();
                this.polygon = this.createCircle(this.map.getMapCenter(),radius,20);
                this.map.addOverlay(this.polygon);
                this.map.setBounds(this.polygon.getBounds(),true);
            }
        }catch(err){}
    },
    /*
        Reset location data
     */
    resetLocation: function(){
        try{ $('latitude').value = 0; }catch(Error){}
        try{ $('longitude').value = 0; }catch(Error){}
        try{ $('filterDistrict').show(); }catch(Error){}
        try{ $('filterCouncil').show(); }catch(Error){}
        try{ $('localDiv').hide(); }catch(Error){}
        try{ $('new-find-me').innerHTML = 'Localização Automática'; }catch(Error){}

    },
    /*
        Try discovery location from navigator Object and get cinemas by proxyLocation
     */
    getLocation: function(radius){
        $('filterPlace').show();//Allway show map
        $('mapDivLnk').addClassName('active');
        
        if( this.map==null )
            this.createMap();

        if(!radius) radius = 5;

        $('new-find-me').innerHTML = 'A detectar...';

        if(navigator.geolocation){
            try{
                var referenceObject = this;
                navigator.geolocation.getCurrentPosition(function(position){
                    referenceObject.getLocationCallback(position.coords.longitude, position.coords.latitude, radius);
                },
                function(error){
                    $('new-find-me').innerHTML = 'Ocorreu um erro. Tente novamente.';
                });
            }catch(err){}
        }else{
            this.getLocationCallback(null, null, radius);
        }
    },
    /*
        By proxy get more location and cinemas details
        @return void
    */
    getLocationCallback: function(lon, lat, radius){
        try{
            var opt = {'radius': radius};
            if(lon!=null && lat!=null){
                opt.longitude = lon;
                opt.latitude = lat;
            }
            new SAPO.Communication.Ajax('/proxyLocation.php', {evalJS:'force', 'parameters':opt, 'onSuccess': function(obj)
            {
                var response = obj.responseJSON;
                this.centerMap(response.longitude, response.latitude, radius);
                this.updateCinemaCallback(response);
                if( response.sussses==false ){

                }
                //confirm lat/lon
                $('latitude').value = response.latitude;
                $('longitude').value = response.longitude;

                this.councilSlug = response.councilSlug;
                this.districtSlug = response.districtSlug;

                //select comboboxs
                $('district').selectedIndex=0;
                for(var i=0; i < $('district').options.length; i++){
                    if($('district').options[i].value==this.districtSlug){
                        $('district').selectedIndex=i;break;
                    }
                }
                $('council').selectedIndex=0;
                for(var i=0; i<$('council').options.length; i++){
                    if($('council').options[i].value==this.councilSlug){
                        $('council').selectedIndex=i;break;
                    }
                }
                $('new-find-me').innerHTML = 'Nova Localização';
            }.bind(this) });
        }catch(Error){
            $('new-find-me').innerHTML = 'Ocorreu um erro. Tente novamente.';
        }
    },
    
    /*
        Make overlay Polygon
        @params center, radius, sides of polygon
        @return Overlay Polygon
     */
    createCircle: function(center, radius, sides){
        radius = Number(radius)*1000+2000;
        var angle = Math.PI * ((1/sides) - (1/2));
        center.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
        var rotatedAngle, x, y;
        var points = [];
        for(var i=0; i<sides; ++i) {
            rotatedAngle = angle + (i * 2 * Math.PI / sides);
            x = center.lon + (radius * Math.cos(rotatedAngle));
            y = center.lat + (radius * Math.sin(rotatedAngle));
            points.push(new OpenLayers.LonLat(x, y).transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")));
        }
        return new SAPO.Maps.Polygon(points, {'fillOpacity':0.3, 'strokeOpacity':0.5 });
    },
    
    /*
        Remove overlay circle
        @return void
     */
    removeCircle: function(){
        if(this.polygon!=null){
            this.map.removeOverlay(this.polygon);
            this.polygon = null;
        }
    },
    
    /*
        Remove all markers
        @return void
     */
    removeMarkers: function(){
        //remove markers layer
        if(this.markersCinema!=null){
            this.map.removeMarkers(this.markersCinema);
            this.markersCinema=null;
        }
    },
    
    /*
        Add Market in this.map
        @return void
    */
    addMarker: function(entity){
        if(this.map==null || this.markersCinema==null) return false;

        var text = '<div class="title"><strong>'+entity.entityName+'</strong><a href="/em-cartaz/cinema/'+entity.entitySlug+'" class="more" title="ver cartaz de '+entity.entityName+'"><span>ver cartaz</span></a></div>';
        if(entity.address) text += '<p>'+entity.address+'</p>';
        if(entity.postalCode1 && entity.postalCode2 && entity.postalCodeLocal ) text += '<p>'+entity.postalCode1+' - '+entity.postalCode2+' '+entity.postalCodeLocal+'</p>';
        if(entity.telephone) text += '<p>Telefone: '+entity.telephone+'</p>';
        if(entity.distance) text += '<p>Distância:'+parseInt(entity.distance)+'</p>';

        try{
            var marker = new SAPO.Maps.Marker(new OpenLayers.LonLat(Number(entity.longitude), Number(entity.latitude)),{}, this.markerStyle );

            marker.registerEvent('click', marker, function(m){ m.openPopup( text ); });
            this.markersCinema.addMarker(marker);
        }catch(err){}
    },

    /*
        Save last request
    */
    cacheCinemas:{},
    /*
        array Markers
     */
    markersCinema:null,
    /*
        Add markers from response AjaxResult
        @return void
     */
    addsMarkers: function(response){
        if(this.map==null) return false;
        if(response) this.cacheCinemas=response;
        try{
            this.removeMarkers();
            this.markersCinema = new SAPO.Maps.Markers('cinemas');
            this.map.addMarkers(this.markersCinema);

        }catch(err){}

        //add markers
        for (var i = 0; i < this.cacheCinemas.items.length; i++)
        {
            if( Number(this.cacheCinemas.items[i].longitude) && Number(this.cacheCinemas.items[i].latitude) ){
                this.addMarker(this.cacheCinemas.items[i]);
            }
        }

        //set bounds
        try{
            if(this.polygon==null){
                this.map.setBounds(this.markersCinema.getBounds(),true);
                this.map.zoomTo(this.map.getZoom()-1);
            }
        }catch(err){}
    }
};

