// change it or set in your HTML
var default_immbro = {
    username : "YourUserName",
    search_limit : 10,
    map : { width: 645, height: 600 }
};

function immbro_config(config) {
    if (! window.immbro)
        window.immbro = {};
    for (var f in config)
        window.immbro[f] = config[f];
}

immbro_config(default_immbro);

immbro.path_api_countries = "http://www.immbro.com/api/countries.json";
immbro.path_api_tags      = "http://www.immbro.com/api/tags.json";
immbro.path_api_search    = "http://www.immbro.com/api/search.json";
immbro.path_api_brochures = "http://www.immbro.com/api/brochures.json";

$(function(){ // on domready

if (window.on_immbro_init)
    window.on_immbro_init();

// === Fields animation, tabs behaviour using jQuery framework ================

// --- wizard-like form behaviour ---------------------------------------------

// when country selected show term field and remove "Select country" option
$('#immbro-search-form select[name=country]').change(function(){
    if (this.value) {
        $('#immbro-search-form > fieldset > .js-show-first').removeClass('js-show-first');
        $('option[value=""]', this).remove();
        $('#term-select').focus();
    }
});
// when term selected show other fields and remove "Select term" option
$('#immbro-search-form select[name=term]').change(function(){
    if (this.value) {
        $('#immbro-search-form fieldset.js-show-second').removeClass('js-show-second');
        $('option[value=""]', this).remove();
        $('#postcode-field').focus();
    }
})
    .get(0).selectedIndex = 0;

// --- tabs -------------------------------------------------------------------

var register_tab = function (tab, page, onclick)
{
    tab  = $(tab);
    tab.data('tab-page', $(page));

    tab.click(function() {
        if (tab.hasClass('selected') ||
            tab.hasClass('disabled'))
            return;
        tab.parents('.tabs:first').find('.tab').each(function() {
            $(this)
                .removeClass('selected')
                .data('tab-page').hide();
        });
        tab.addClass('selected');
        tab.data('tab-page').show();
        if (onclick)
            return onclick.call(this);
        else
            return true;
    });
    $(page)[ tab.hasClass('selected') ? 'show' : 'hide' ]();
}

var return_false = function() { return false; }

register_tab('#tab-search', '#immbro-search-form', return_false);
register_tab('#tab-tags',   '#immbro-tags-section', return_false);

register_tab(
    '#tab-list', 
    '#immbro-search-results-list', 
    function() { 
        window.is_map_selected = false; 
    }
);
register_tab(
    '#tab-map',  
    '#immbro-search-results-map', 
    function() {
        window.is_map_selected = true;
        immbro_search_show_map();
    }
);

if (location.hash == '#results-map')
    window.is_map_selected = true;

// --- data init --------------------------------------------------------------

/**
 * api/countries.json
 * params: jsonp - name of callback, optional
 * returns [ COUNTRY, COUNTRY, ... ]
 * COUNTRY := { value: "GB", display: "United Kingdom" }
 */
$.getJSON(immbro.path_api_countries +"?jsonp=?",
function(countries) {
    $.each(countries, function() {
        $('#country-select').append(
            '<option value="'+ this.value +'">'+ this.display + '</option>'
        );
    });
});

/**
 * api/tags.json
 * params: jsonp - name of callback, optional, username
 * returns [ TAG, TAG, ... ]
 * TAG := { name: TEXT, description: TEXT }
 */
if ($("#immbro-tags-template").size() > 0) {
    $.getJSON(
        immbro.path_api_tags +"?jsonp=?",
        { username: immbro.username },
        // on success:
        function (tags) {
            jst('immbro-tags-template').render({tags: tags});
            if (window.loadAfterTags)
                window.loadAfterTags();
            else
                window._tagsLoaded = true;
            return;
        }
    );
}

$(window).ajaxError(function(){
    immbro_search_info("Unknown error occured, please try again later.");
});

// --- if passed ?query arguments do immediate search - to make search form anywhere
// also can be userd to make short search form

// load maps
setTimeout(immbro_init_gmaps, 100);

if (window.location.search) {
    var params = {};
    var query = window.location.search.substr(1);
    $.each(query.split('&'), function(){
        var pair = this.split('=');
        params[unescape(pair[0])] = unescape(pair[1]);
    });
    if (! params.tag) {
        // show all form fields
        $('#immbro-search-form > fieldset > .js-show-first').removeClass('js-show-first');
        $('#immbro-search-form fieldset.js-show-second').removeClass('js-show-second');
        $('#immbro-search-form select option[value=""]').remove();
        // fill form fields with search values
        var form = $('#immbro-search-form').get(0);
        for (var name in params)
            if (form.elements[name])
                form.elements[name].value = params[name];
        // do search
        immbro_search(params);
    }
    else {
        // tag search requires other functions, because api/search requires term & country
        window.loadAfterTags = function() {
            $('#tab-tags').click(); // open Tags accordion section
            setTimeout(function() {
                immbro_show_tagged(params.tag);
            }, 200);
        }
        if (window._tagsLoaded)
            window.loadAfterTags();
    }
}

}); // endof jQuery domready

// ===  map init ==============================================================

immbro_search_clear_results_on_map = function() {};

function immbro_init_gmaps()
{
    if (! GBrowserIsCompatible || !GBrowserIsCompatible())
        return;

    marker_icon_property = new GIcon(G_DEFAULT_ICON, 'http://www.immbro.com/media/share/marker_property.png');
    marker_icon_properties = new GIcon(G_DEFAULT_ICON, 'http://www.immbro.com/media/share/marker_properties.png');

    // set map size or some bugs will present
    immbro_search_map = new GMap2(
        document.getElementById("immbro-search-results-googlemap"),
        { size: new GSize(immbro.map.width, immbro.map.height) });

    immbro_search_map.setCenter(new GLatLng(51.32, 0.06), 9);
    immbro_search_map.addControl(new GLargeMapControl());
    immbro_search_map.addControl(new GMapTypeControl());
    immbro_search_map.addControl(new GScaleControl(300));

    // clear results function
    immbro_search_clear_results_on_map = function() {
        immbro_search_map.clearOverlays();
        immbro_search_map_points = [];
    };

    // list of GLatLng points on map with attached property description,
    // filled by immbro_search_show_results_on_map
    immbro_search_map_points = [];

    window.immbro_map_loaded = true;
}
  
// show results function, json object, returned by search api passed
immbro_search_show_results_on_map = function(search)
{
    if (! window.immbro_map_loaded) return;
    
    var popups = {};
    $.each(search.results, function() {
        var point = new GLatLng(
            parseFloat(this.property.latitude),
            parseFloat(this.property.longitude)
        );
        var t = this.property.latitude + "," + this.property.longitude;
        if (! popups[t])
            popups[t] = { point: point, brochures: [] };
        popups[t].brochures = popups[t].brochures.concat(this.brochures);
    });

    immbro_search_map_popups = [];
    for (var k in popups) {
        for (var i = 0; i < popups[k].brochures.length; i++) {
            var node = $('<div class="search-result-popup"/>').get(0);
            jst('immbro-map-infowindow').renderTo(node, popups[k].brochures[i]);
            popups[k].brochures[i] = node;
        }
        immbro_search_map_popups.push(popups[k]);
    }

    $.each(immbro_search_map_popups, function() {
        if (this.brochures.length > 1) {
            this.popup = document.createElement('div');
            this.label = 'There are '+
                this.brochures.length + ' properties at this location';
            var popup = $(this.popup);
            popup.addClass('search-result-popup-container');
            popup.append('<p class="multiple">There are '+
                this.brochures.length + ' properties at this location</p>');
            popup.append(this.brochures[0]);
            var n = $('<p class="navigation">' +
                '<span class="previous"><a href="#previous">Previous</a> | </span>' +
                '<span class="title">1st property</span>' +
                '<span class="next"> | <a href="#next">Next</a></span></p>'
            );
            popup.append(n);

            var self = this;
            self.index = 0;
            var fillContent = function() {
                popup.find('div.search-result-popup').replaceWith(self.brochures[self.index]);
                popup.find('p.navigation > span.title').text((self.index + 1) +
                    (self.index == 0 ? 'st' :
                        (self.index == 1 ? 'nd' : (self.index == 2 ? 'rd' : 'th'))) +
                    ' property');
            };
            n.find('.previous a').click(function(){
                --self.index;
                fillContent();
                if (self.index == 0)
                    popup.find('p.navigation > .previous').hide();
                if (self.index == self.brochures.length - 2)
                    popup.find('p.navigation > .next').show();
                return false;
            });
            n.find('.previous').hide();
            n.find('.next a').click(function(){
                ++self.index;
                fillContent();
                if (self.index == self.brochures.length - 1)
                    popup.find('p.navigation > .next').hide();
                if (self.index == 1)
                    popup.find('p.navigation > .previous').show();
                return false;
            });
        }
        else {
            this.popup = this.brochures[0];
            this.label = $(this.brochures[0]).find('h2').text().replace(/\s+/g, ' ');
        }
    });

    immbro_search_update_map();
};

// show properties, parsed by immbro_search_show_results_on_map
immbro_search_update_map = function()
{
    immbro_search_map.clearOverlays();

    var bounds = new GLatLngBounds();
    $.each(immbro_search_map_popups, function() {
        var marker = new GMarker(this.point, {
            icon: this.brochures.length == 1 ? marker_icon_property : marker_icon_properties,
            title: this.label
        });
        // for each marker create popup window
        marker.bindInfoWindow(this.popup, {maxWidth:300});
        immbro_search_map.addOverlay(marker);
        // bounds to adjust proper pan & zoom
        bounds.extend(this.point);
    });
    immbro_search_map_bounds = bounds;
    // adjust pan & zoom
    immbro_search_show_map();
};

// adjust map pan & zoom
immbro_search_show_map = function()
{
    if (! window.immbro_map_loaded) return;    
    
    immbro_search_map.checkResize();
    // if no properties - do nothing
    if (immbro_search_map_popups.length == 0) return;
    // if one property - zoom it
    if (immbro_search_map_popups.length == 1)
        immbro_search_map.setCenter(immbro_search_map_popups[0].point, 15);
    // if many - zoom to show them all
    else {
        immbro_search_map.setCenter(
            immbro_search_map_bounds.getCenter(),
            immbro_search_map.getBoundsZoomLevel(immbro_search_map_bounds)
        );
    }
}

// === immbro search ==========================================================

// show info or error message
function immbro_search_info(info, className)
{
    $('#immbro-search-results-tab-list').click();
    $('#immbro-search-results-tab-map').addClass('disabled');
    immbro_search_clear_results_on_map();
    $('#immbro-search-results-list > table').hide();
    $('#no-results').html(info).show();
    $('#no-results').get(0).className = className;
    $('#search-results-navigation').hide();
}

// format price of property
function immbro_formatPrice(price, currency, term)
{
    var pw = ' <abbr title="per week">pw</abbr>';
    if (immbro_formatPrice_formats[currency])
        return immbro_formatPrice_formats[currency](price) + (term != 'sale' ? pw : '');
    else
        return immbro_formatPrice_formats._default(price, currency)
            + (term != 'sale' ? pw : '');
}

// called by immbro_formatPrice
immbro_formatPrice_formats = {
  GBP : function(price) {
      if (! price) return '';
      var t = [];
      while (price.length > 3) {
          t.unshift(price.substr(price.length - 3, 3));
          price = price.substr(0, price.length - 3);
      }
      if (price) t.unshift(price);
      return '&pound;' + t.join(',');
  },
  _default: function(price, currency) {
      return price + currency;
  }
};

// show search results list & map
function immbro_search_show_results(search)
{
    $('#no-results').hide();
    $('#immbro-search-results-list > table').show();

    // see results format at immbro_search function description
    // making brochures list with reference to its property
    // as one property can have many brochures
    var brochures = [];
    $.each(search.results, function(){
       var property = this.property;
       $.each(this.brochures, function(){
          this.property = property;
          // also formatting price here
          var term = window.search_term || 
              (this.sale.status.value ? 'sale' : null) ||
              (this.rent_long.status.value ? 'rent_long' : null) || 
              'rent_short';
          this.formatted_price = immbro_formatPrice(
            this[term].price, this.currency.value, term);
          brochures.push (this);
       });
    });
    // renders results list with jst templater
    // edit template at #search-results-template
    jst('search-results-template').render({brochures: brochures});

    // parse result for map view
    immbro_search_show_results_on_map(search);

    // render pagination template
    jst('search-results-navigation').render({
        offset: parseInt(search.offset),
        count : brochures.length,
        limit : immbro.search_limit,
        total : parseInt(search.total)
    });
    $('#search-results-navigation').show();

    $('#tab-map').removeClass('disabled');
    if (window.is_map_selected)
        $('#tab-map').click();
}

// shows errors
function immbro_search_errors(errors)
{
    var msgs = [];
    for (var key in errors)
        msgs.push( '<li>' + key +
        ': <span>' + errors[key].join("</span><spen>") + '</span></li>'
        );
    immbro_search_info('<ul class="errors">' + msgs.join() + '</ul>');
}

// search function, form is form element ID or params hash itself, offset is 0 by default
function immbro_search(form, offset)
{
    // show "Searching..." label
    immbro_search_info("Searching...", 'loading');

    var params;
    // if form ID passed - parse form values
    if (typeof(form) == 'string') {
        params = {};
        form = $('#' + form)[0];
        var keys = [
            'country','term','postcode','pmin','pmax',
            'bmin','bmax','keyword'
        ];
        for (var i in keys)
            if (form.elements[keys[i]] && form.elements[keys[i]].value)
                params[keys[i]] = form.elements[keys[i]].value;

        params.limit = immbro.search_limit;
    }
    else
        params = form;

    if (offset)
        params.offset = offset;

    // search_url_results is used to make link to search page
    params.search_url_results = location.protocol + '//' + location.host + 
        location.pathname + '?' + $.param(params) + location.hash;

    // whose phoperties we are searching?
    if (immbro.username)
        params.username = immbro.username;

    // store params to make pagination by changing offset only
    immbro_last_search_params = params;

    // what we are looking for? is used in immbro_formatPrice
    window.search_term = params['term'];

    /**
     * api/search.json
     * params:
     * - search criterias:
     *   country REQUIRED, postcode, keyword /-searched in area, street, description-/,
     *   term := {sale, rent_short, rent_long} REQUIRED, 
     *   pmin, pmax /-price min & max-/, 
     *   bmin, bmax /-bedrooms count min, max-/,
     *   username /-property owner user-/, tag, id /-id of brochure to search-/
     * - other:
     *   jsonp /-callback-/, offset, limit, random /-if set, only one random result returned-/
     * returns:
     *   { results: RESULTS, total: NUMBER, limit: NUMBER-OR-NULL, offset: NUMBER, errors: ERRORS }
     *   RESULTS  := [ RESULT, RESULT, ... ]
     *   RESULT   := { brochures: [ BROCHURE, BROCHURE, ... ], property: PROPERTY }
     *   BROCHURE := { 
     *     rent_short: TERM, sale: TERM, rent_long: TERM, url_page: URLS, 
     *     text_intro /-short description-/, text_description /-long description-/,
     *     photos: [ PHOTO, PHOTO, ... ], currency: { value: TEXT-ID, display: TEXT },
     *     contact: CONTACT, tenure: { value: NUMBER-ID, display: TEXT }, id: NUMBER-ID
     *   }
     *   TERM     := { 
     *     status: { value: NUMBER-ID /-0 if not active term-/, description: TEXT },
     *     comment: TEXT, price: NUMBER-AS-TEXT, date_available: TEXT /-not nesessery-/,
     *     furnishing: { value: NUMBER-ID, display: TEXT } /-for rent_* terms only-/
     *   }
     *   URLS     := { 
     *     overview: URL, documents: URL, terms: URL, features: URL, photos: URL,
     *     floorplans: URL, location: URL, pdf: URL /-url to immbro pages of this brochure,
     *     any of it except 'overview' is not nesessery and can be omitted if no such page-/
     *   }
     *   PHOTO    := { 
     *     width: NUMBER, height: NUMBER, extension: ".EXT", path: TEXT }
     *     (original_photo_url = path + "/Any_name" + extension;)
     *     (thumbnail_url = path + "/150x150/Any_name" + extension;)
     *     /-avaliable thumbnail sizes can be changed in future, please contact-/
     *   CONTACT  := { 
     *     first_name: TEXT, last_name: TEXT, 
     *     phone_fixed: ["country-code","area-code","phone-number"], phone_mobile: ["code", "number"],
     *     title: { value: NUMBER-ID, display: TEXT } /-Mr., Mrs. or else-/, email: TEXT
     *   }
     *   PROPERTY := { 
     *     floor_min: { value: NUMBER, description: TEXT }, street_no: NUMBER-AS-TEXT,
     *     countof_bathroom: NUMBER, countof_bedroom: NUMBER, street: TEXT, postcode: TEXT,
     *     postcode2: TEXT, aspect: { value: NUMBER-ID, display: TEXT }, id: NUMBER-ID, 
     *     city: TEXT, sqm_floor_space: NUMBER, house_name: TEXT, area: TEXT, 
     *     country: { value: TEXT-ID, display: TEXT }, c_floors: NUMBER /-count of floors-/,
     *     longitude: NUMBER-AS-TEXT, latitude: NUMBER-AS-TEXT, apt_no: TEXT /-apartment number-/,
     *     type: { value: NUMBER-ID, display: TEXT }
     *   }
     *   ERRORS   := null or { "element": REASONS, "element": REASONS, ... }
     *   REASONS  := [ TEXT, TEXT, ... ]
     *     /- for example 
     *      ERRORS = { "term": [ "Select a valid choice. rent is not one of the available choices."] } 
     *      -/
     */
    $.getJSON(
        immbro.path_api_search +"?jsonp=?",
        params,
        // on succes:
        function (search) {
            if (search.errors) {
                immbro_search_errors(search.errors);
                return;
            }
            if (search.results.length == 0) {
                immbro_search_info("No properties match the given criteria.");
                return;
            }
            immbro_search_show_results(search);
            return;
        }
    );
}

// pagination action, searches next portion
function immbro_search_next()
{
    if (! immbro_last_search_params.offset)
        immbro_last_search_params.offset = immbro.search_limit;
    else
        immbro_last_search_params.offset += immbro.search_limit;
    immbro_search(immbro_last_search_params);
}

// pagination action, searches previous portion
function immbro_search_prev()
{
    if (! immbro_last_search_params.offset)
        immbro_last_search_params.offset = 0;
    else
        immbro_last_search_params.offset -= immbro.search_limit;
    immbro_search(immbro_last_search_params);
}

// === tagged brochures search ================================================

// search tagged brochures, can't use api/search because it requires term & country fields
function immbro_show_tagged(tag)
{
    if ( $('#tag-header-' + tag.replace(/\W/g,'')).hasClass('active') ) 
        return false;

    immbro_search_info("Loading...", 'loading');
    search_term = null;
    /**
     * api/brochures.json
     * params: jsonp, username, tag, random
     * returns same as api/search.json
     */
    $('#immbro-tags-template > li > h3').removeClass('active');
    $('#tag-header-' + tag.replace(/\W/g,'')).addClass('active');
    $.getJSON(
        immbro.path_api_brochures +"?jsonp=?",
        {
            username           : immbro.username,
            tag                : tag,
            search_url_results : location.protocol + '//' + location.host + 
                location.pathname + '?' + $.param({ tag: tag }) + location.hash
        },
        // on succes:
        function (search) {
            if (search.errors) {
                immbro_search_errors(search.errors);
                return;
            }
            if (search.results.length == 0) {
                immbro_search_info("Sorry, there's no properties with that tag.");
                return;
            }
            immbro_search_show_results(search);
            return;
        }
    );
    return false;
}
