/**
 * BlueVendo ASP 3.4 - Hotel Booking Engine
 *
 * @copyright Synerway S.A. 2008 - www.synerway.pl
 * @author Artur Kozubski <a.kozubski@synerway.pl>
 *
 * Główny skrypt wyszukiwarki umieszczanej na stronie klienta.
 */

// Kodowanie: UTF-8
// Konfiguracja (podstawowa - trzeba koniecznie ustawić dwie poniższe zmienne zgodnie ze wskazówkami w skrypcie startowym PHP)

// Adres plików m.in. z szablonami i skryptami javascript
var base_url = 'http://orbis.synerway.pl/client/orbis/';
// Adres pliku ze stylami - "style.css"
// Uwaga: adres styli css może być nadpisany przez ustawienia specyficzne dla serwisu partnerskiego odwołującego się do tego skryptu
var style_url = 'http://orbis.synerway.pl/client/orbis/css/';
var css_url_main = style_url + 'style.css'; // Style główne
var css_url_lightbox = style_url + 'lightbox.css'; // Style lightBox
var css_url_calendar = style_url + 'jscalendar/calendar-blue.css'; // Style jsCalendar
// addr es modułu odzyskiwania/zmiany hasła użytkownika BlueVendo (klienta)
var chg_user_pwd_addr = 'http://orbis.synerway.pl/user.php';
// Wymiary mapy Google
var gmap_width = 600;
var gmap_height = 450;
// Szerokość ikony zamykającej mapę Google (X)
var gmclose_icon_width = 16;
// Wyrównanie ikony (padding w #BVAction_close_gmap)
var gmclose_icon_padding = 10;
// Wysokość belki komunikatu pomocniczego (height w #close_msg_bar)
var gmap_msg_bar_height = 30;
// Wyrównanie belki komunikatu pomocniczego (padding w #close_msg_bar)
var gmap_msg_bar_padding = 10;
// Pionowy odstęp między komunikatem "Proszę czekać", a animacją wskaźnika postępu
var ajaxMsgVertMargin = 20;
// Włączanie i wyłączanie korzystania z Google Maps
// Uwaga: opcja może być nadpisana przez ustawienia specyficzne dla serwisu partnerskiego odwołującego się do tego skryptu
var use_gmaps = false;
// Strona z której jest wywoływana wyszukiwarka (adres bazowy)
var client_base_url = window.location;
//------------------------------------------------------------------------------

// Konfiguracja (dodatkowa - ustawiana w skrypcie startowym PHP klienta, nadpisanie w JS opcjonalne)

var is_map = false;
// Czy ukrywać wyszukiwarkę po otwarciu szczegółów hotelu
var hide_search_form = false;
// Czy ukrywać panel logowania po otwarciu szczegółów hotelu
var hide_loginbox = false;
// Adres na który ma nastąpić przekierowanie po wydrukowaniu/pobraniu formularza przelewu
var redir_payform_print = "";

// Automatyczne wyszukiwanie po załadowaniu strony
var auto_search = false;

// Domyślne daty w wyszukiwarce - nadpisanie ustawień konfiguracji w PHP (ustawić na null aby wyłączyć)

// Ilość dni dodana do bieżącej daty (data rozpoczęcia rezerwacji)
var start_service = null;
// Ilość dni rezerwacji - długość
var end_service = null;

var servicetime = end_service - start_service;
var params_present = false;
var checkin, checkout;
var searchresultids;

// Blokada wyszukiwarki (blokuje przycisk "Szukaj")
var searchEnabled = true;

// Klucz Google Maps API
var google_maps_api_key;

// Dane zalogowanego użytkownika (głównie na potrzeby kont agentów)
var is_agent = false;         // Informacja czy zalogowany jest agent (może też być zwykły user)
var auth_user = false;        // Informacja czy z wyszukiwarki korzysta zalogowany użytkownik
var session_id = null;        // ID sesji zalogowanego użytkownika
var deferred_payment = false; // Czy płatności odroczone są dostępne

//------------------------------------------------------------------------------
// FUNKCJE POMOCNICZE
//------------------------------------------------------------------------------

function loadScript(url)
{
    document.write('<script src="', url, '" type="text/javascript"></script>');
}


function loadStyle(url)
{
    document.write('<link rel="stylesheet" href="', url, '" type="text/css" media="all" />');
}


/*
 * Obsługa cookies na potrzeby zapamiętywania wybranego języka.
 */

// Ustawia cookie
function setCookie(name, value, expireTime, sessionCookie)
{
    if (!sessionCookie) {
        expDate = new Date();
        expDate.setDate(expDate.getDate() + expireTime);
        document.cookie = name + "=" + escape(value) + ((expireTime == null) ? "" : ";expires=" + expDate.toGMTString());
    } else document.cookie = name + "=" + escape(value);
}


// Pobiera cookie
function getCookie(name)
{
    if (document.cookie.length > 0) {
        start = document.cookie.indexOf(name + "=");
        if (start != -1) {
            start = start + name.length + 1;
            end = document.cookie.indexOf(";", start);
            if (end == -1) end = document.cookie.length;
            return unescape(document.cookie.substring(start, end));
        }
    }

    return "";
}


// Pobiera query string bieżącej strony
function getQueryStringParam(paramName)
{
    qryStr = window.location.search.substring(1);
    qryStrArr = qryStr.split("&");

    for (i = 0; i < qryStrArr.length; i++) {
        param = qryStrArr[i].split("=");
        if (param[0] == paramName) return param[1];
    }

    return "";
}


// Pobiera miasto z bieżącego adresu URL
function getCityFromURL()
{
    var idx = window.location.href.indexOf('hotele,'); 
	if (idx != -1) {
		var cityName = window.location.href.substring(idx + 7).replace('/', '');
        return cityName;
    }

    return '';
}


// Ustawia parametry wyszukiwarki
var inputParam = "";
var hotelParam = "";
var startDataParam = "";
var endDataParam = "";
var codeParam = "";
var categoryParam = "";
var hotel_placeid = "";
var param;
var qS = window.location.search.substring(1);
var qSArr = qS.split("&");

for (ii = 0; ii < qSArr.length; ii++) {
    param = qSArr[ii].split("=");

    if (param[0] == "BV3input")
        inputParam = url_decode(param[1]);
    else if (param[0] == "BV3hotel")
        hotelParam = url_decode(param[1]);
    else if (param[0] == "BV3startData")
        startDataParam = param[1];
    else if (param[0] == "BV3endData")
        endDataParam = param[1];
    else if (param[0] == "BV3code")
        codeParam = param[1];
    else if (param[0] == "BV3category")
        categoryParam = param[1];
	else if (param[0] == "BV3hotelid")
	   hotel_placeid = param[1];
}

var cityName = getCityFromURL(); 
if (cityName != '') inputParam = url_decode(cityName);

// Pobranie ewentualnego ID sesji przekazanego w url-u
var sid = getQueryStringParam('sid');
if (sid == '') getQueryStringParam('SESSIONID');


function isThousands(position)
{
    if (Math.floor(position / 3) * 3 == position) return true;
    return false;
}


// Formatuje liczbę (zapis kwoty pieniężnej)
function formatMoney(theNumber, theCurrency, theThousands, theDecimal)
{
    var theDecimalDigits = Math.round((theNumber * 100) - (Math.floor(theNumber) * 100));

    theDecimalDigits = '' + (theDecimalDigits + '0').substring(0, 2);
    theNumber = '' + Math.floor(theNumber);

    var theOutput = theCurrency;

    for (x=0; x<theNumber.length; x++) {
        theOutput += theNumber.substring(x, x + 1);
        if (isThousands(theNumber.length - x - 1) && (theNumber.length - x - 1 != 0)) {
            theOutput += theThousands;
        }
    }
    theOutput += (parseInt(theDecimalDigits) > 0 ? theDecimalDigits + theDecimal : '');

    return theOutput;
}


// Zwraca wersję IE
function getInternetExplorerVersion()
{
    var rv = -1;

    if (navigator.appName == 'Microsoft Internet Explorer') {
        var ua = navigator.userAgent;
        var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null) rv = parseFloat(RegExp.$1);
    }

    return rv;
}


// Pobranie wersji IE
var ie_ver = getInternetExplorerVersion();


// Pobranie pozycji XY elementu
function findElemPos(elm)
{
    var posX = elm.offsetLeft;
    var posY = elm.offsetTop;

    while (elm.offsetParent) {
        posX += elm.offsetParent.offsetLeft;
        posY += elm.offsetParent.offsetTop;

        if (elm == document.getElementsByTagName('body')[0])
            break;
        else
            elm = elm.offsetParent;
    }

    return [posX, posY];
}


// Wyświetla wskaźnik ładowania AJAX
function showAJAXLoadIndicator(msg, id)
{
    if (id == null) id = 'BV_content';

	$('body').append('<div id="ajax_load_progress" style="background: white; position: absolute; z-index: 100"><img id="ajax_wait_anim" class="ajaxloaderimg" src="' + base_url + 'images/ajaxloader.gif" style="display: block; margin-left: auto; margin-right: auto; padding-top: 10px" /></div>');

    ajaxImgWidth = $('#ajax_wait_anim').width();
    ajaxImgHeight = $('#ajax_wait_anim').height();

    contentWidth = $('#' + id).width();
    contentHeight = $('#' + id).height();

    if (!contentWidth) contentWidth = 2 * ajaxImgWidth;
    if (!contentHeight) contentHeight = 2 * ajaxImgHeight;
	if (contentHeight < 2 * ajaxImgHeight) contentHeight = 2 * ajaxImgHeight;

    $('#ajax_load_progress').width(contentWidth);
    $('#ajax_load_progress').height(contentHeight);

    contentPos = findElemPos(document.getElementById(id));

    $('#ajax_load_progress').css('left', contentPos[0] + 'px');
    $('#ajax_load_progress').css('top', contentPos[1] + 'px');

    $('body').append('<div id="ajax_load_progress_msg" class="ajax_loader">' + msg + '</div>');
    $('#ajax_load_progress_msg').width($('#' + id).width());

    loadIndPos1 = findElemPos(document.getElementById('ajax_load_progress'));
	loadIndPos2 = findElemPos(document.getElementById('ajax_wait_anim'));

    $('#ajax_load_progress_msg').css('left', loadIndPos1[0] + 'px');
	$('#ajax_load_progress_msg').css('top', loadIndPos2[1] + ajaxImgHeight + ajaxMsgVertMargin + 'px');
    $('#' + id).css('visibility', 'hidden');
}


// Ukrywa wskaźnik ładowania AJAX
function hideAJAXLoadIndicator(id)
{
    if (id == null) id = 'BV_content';

    $('#ajax_load_progress_msg').remove();
    $('#ajax_load_progress').remove();
    $('#' + id).css('visibility', 'visible');
}


// Wyświetla wskaźnik ładowania danych do listy autopodpowiedzi miast, regionów i państw (AJAX)
function showAutoCompleteProgress()
{
// TO DO
}


// Ukrywa wskaźnik ładowania danych do listy autopodpowiedzi miast, regionów i państw (AJAX)
function hideAutoCompleteProgress()
{
// TO DO
}


// Wyświetla warstwę dla mapy Google (type: 0 - mapa z pozycją obiektu, 1 - mapa do wyznaczania odległości)
function showGoogleMap(type)
{
    var body_elem = document.body;
    var body_height  = body_elem.offsetHeight;
    var pageYOffset = window.pageYOffset;

    searchEnabled = false;

    if (!type)
        exit_msg = translation_close;
    else
        exit_msg = translation_gmaps_dist;

    if (ie_ver > 0 && ie_ver < 7) $('body').append('<iframe id="IE6_SELECT_HIDE" style="position: absolute"></iframe>');
    $('body').append('<div style="position: absolute" id="GMapLayer"><div id="mapcontent"></div><div id="close_msg_bar">' + exit_msg + '</div><div id="BVAction_close_gmap"><img src="' + base_url + 'images/icons/button_cancel.gif" /></div></div>');

    // Scroll - wartości
    var scrOfX = 0, scrOfY = 0;

    if (typeof(window.pageYOffset) == 'number') {
        // Netscape compliant
        scrOfX = window.pageXOffset;
        scrOfY = window.pageYOffset;
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
        // DOM compliant
        scrOfX = document.body.scrollLeft;
        scrOfY = document.body.scrollTop;
    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
        // IE6 standards compliant mode
        scrOfX = document.documentElement.scrollLeft;
        scrOfY = document.documentElement.scrollTop;
    }

    // Detekcja wymiarów okna (wnętrza)
    if (navigator.appName == "Netscape") {
        winW = window.innerWidth;
        winH = window.innerHeight;
    } else {
        winW = document.body.offsetWidth;
        winH = document.body.offsetHeight;
    }

    gmap_pos_x = scrOfX + (winW - gmap_width) / 2;
    gmap_pos_y = scrOfY + (winH - gmap_height - gmap_msg_bar_height - 2 * gmap_msg_bar_padding + 1) / 2;

    if (ie_ver > 0 && ie_ver < 7) {
        $('#IE6_SELECT_HIDE').width(gmap_width);
        $('#IE6_SELECT_HIDE').height(gmap_height + gmap_msg_bar_height + 2 * gmap_msg_bar_padding + 1);
        $('#IE6_SELECT_HIDE').css('left', gmap_pos_x + 'px');
        $('#IE6_SELECT_HIDE').css('top', gmap_pos_y + 'px');
    }

    $('#GMapLayer').width(gmap_width);
    $('#GMapLayer').height(gmap_height + gmap_msg_bar_height + 2 * gmap_msg_bar_padding + 1);
    $('#GMapLayer').css('left', gmap_pos_x + 'px');
    $('#GMapLayer').css('top', gmap_pos_y + 'px');
    $('#mapcontent').width(gmap_width);
    $('#mapcontent').height(gmap_height);
    $('#BVAction_close_gmap').css('left', (gmap_width - gmclose_icon_width - 2 * gmclose_icon_padding) + 'px');
    $('#close_msg_bar').width(gmap_width - 2 * gmap_msg_bar_padding);

    $('#BVAction_close_gmap').click(function() {
        hideGoogleMap();
    });

    document.onkeyup = function(e) {
        if (e == null) { // IE
            keycode = event.keyCode;
        } else { // Mozilla
            keycode = e.which;
        }

        if (keycode == 27) {
            // Esc - Zamknij mapę
            hideGoogleMap();
        }
    };
}


// Chowa warstwę dla mapy Google
function hideGoogleMap()
{
    document.onkeyup = '';
    ie_ver = getInternetExplorerVersion();
    if (ie_ver > 0 && ie_ver < 7) $('#IE6_SELECT_HIDE').remove();
    $('#mapcontent').remove();
    $('#close_msg_bar').remove();
    $('#BVAction_close_gmap').remove();
    $('#GMapLayer').remove();

    searchEnabled = true;
}


// Składa kilka hashy w jeden string
function joinHash(h)
{
    if (h[0].length > 1) {
        var s = h[0];
        var i = 1;

        while (i < h.length) {
            s = s + ',' + h[i];
            i++;
        }

        return s;
	}

    return h;
}


var XMLHttpFactories =
[
    function () {return new XMLHttpRequest()},
    function () {return new ActiveXObject("Msxml2.XMLHTTP")},
    function () {return new ActiveXObject("Msxml3.XMLHTTP")},
    function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];


// Funkcja tworząca obiekt XMLHTTPRequest
function createXMLHTTPObject()
{
    var xmlhttp = false;

    for (i = 0; i < XMLHttpFactories.length; i++) {
        try {
            xmlhttp = XMLHttpFactories[i]();
        } catch (e) {
            continue;
        }
        break;
    }

    return xmlhttp;
}


// Funkcja wysyłająca żądanie HTTP do podanego hosta (adres hosta, funkcja zwrotna odbierająca odpowiedź hosta, metoda - GET, POST)
// Jeśli nie podamy ostatniego parametru to zostanie wykonane wywołanie metodą GET.
// Uwagi: Używać gdy metody jQuery: $().get() i $().post() są niedostępne. Pobranie jest asynchroniczne.
function sendRequest(url, callback, postData)
{
    var req = createXMLHTTPObject();
    if (!req) return;

    var method = postData ? "POST" : "GET";

    req.open(method, url, true);
    req.setRequestHeader("User-Agent", "XMLHTTP/1.0");
    if (postData) req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    req.onreadystatechange = function() {
		if (req.readyState != 4) return;
		try {
			if (req.status != 200 && req.status != 304) return;
			callback(req);
		} catch (e) {}
	};

    if (req.readyState == 4) return;
    req.send(postData);
}


// Ajaxowe pobranie strony metodą GET (synchroniczne)
function getAJAX(url2get)
{
    var req = createXMLHTTPObject();
    if (!req) return;

    req.open('GET', url2get, false);
    req.setRequestHeader("User-Agent", "XMLHTTP/1.0");
    req.send(null);

    return req.responseText;
}

//-----------------------------------------------------------------------------------
// Parametry wywołania - akcja do wykonania
var bv_action = getQueryStringParam('bvaction');

var b_log = false;
var b_pas = false;

var start_now = false;
var from_lng = 0.0;
var from_lat = 0.0;
var rowLastColor = '';

var destination = null;
var curListPage = 0, curSortField, curOrder;
var curReservPage = 0, curReservSortField, curReservOrder;
var selected_currencyid;

// Język (pobranie nazwy języka z query string, jeśli brak to z cookies, inaczej ustawienie cookie)
var cur_lng = getQueryStringParam('current_lang');
var langid = 1;

if (cur_lng == "") {
    cur_lng = getCookie('cur_lang');
    if (cur_lng == "") cur_lng = 'polish';
} else {
    setCookie('cur_lang', cur_lng, 0, true);
}

switch (cur_lng) {
    case 'english':
       langid = 2;
       break;

    case 'german':
       langid = 5;
       break;      
}


// Alternatywny referer dla walidacji odwołań (IE czasami nie przekazuje referera w żądaniach HTTP)
var wloc = String(window.location);
var idx = wloc.indexOf('#');
if (idx >= 0) wloc = escape(wloc.substr(0, idx));

// Dodatkowe paramery wywołania ajaxproxy.php (do przekazywania kodu języka, ale można dodawać swoje)
var extra_params = 'altref=' + wloc + '&current_lang=' + cur_lng;

// Komunikaty - tłumaczenia
eval(getAJAX(url + 'ajaxproxy.php?step=51&hash=' + joinHash(hash) + '&' + extra_params));

//-- Załadowanie zewnętrznych bibliotek JS ------------------------------------------

// Pobranie konfiguracji aktualnego serwisu z serwera BlueVendo
var site_config = getAJAX(url + 'ajaxproxy.php?step=50&hash=' + joinHash(hash) + '&' + extra_params);
var site_config_array = site_config.split(',');

if (google_maps_api_key == '' || google_maps_api_key == null) google_maps_api_key = site_config_array[0];
use_gmaps = (site_config_array[1] == 't' ? true : false);
css_url_main = site_config_array[2];
css_url_lightbox = site_config_array[3];
css_url_calendar = site_config_array[4];

// Google Maps API v2.0
if (use_gmaps) loadScript('http://maps.google.com/maps?file=api&v=2&key=' + google_maps_api_key);

// Zewnętrzne biblioteki JavaScript
loadScript(base_url + "js/jquery.js");                               // jQuery
loadScript(base_url + "js/jquery.lightbox.js");                      // jQuery lightBox
loadScript(base_url + "destination/cdajax.js");                      // Cross Domain AJAX
loadScript(base_url + "jscalendar/calendar_stripped.js");            // jsCalendar
loadScript(base_url + "jscalendar/lang/calendar-" + langid + ".js"); // jsCalendar
loadScript(base_url + "jscalendar/calendar-setup_stripped.js");      // jsCalendar

// Style CSS
loadStyle(css_url_main);     // Style główne
loadStyle(css_url_lightbox); // Style lightBox
loadStyle(css_url_calendar); // Style jsCalendar

// Koniec konfiguracji
//------------------------------------------------------------------------------


function setDestination(element)
{
    destination = element;
}


function rowHighlight(row, highlight)
{
    if (highlight) {
        rowLastColor = $(row).css('background-color');
        $(row).css('background-color', 'rgb(210, 218, 255)');
    } else {
        $(row).css('background-color', rowLastColor);
    }
}


/**
 * Walidacja danych wejściowych do rejestracji użytkownika.
 */
function validate(value,type,firm,name)
{
    if ($('#log').val() > 0) {
        if (type != 'pstring') return true;
    }

    var reg = /^firm/;

    if (firm == 0) {
        if (reg.test(name)) return true;
    }

    switch(type) {
        case 'select':
        case 'checkbox' :
        case 'nullstring' :
        case 'opt':
            return true;

        case 'string' :
            reg = /\w+/;
            return reg.test(value);

        case 'number' :
            reg = /\d+/;
            return reg.test(value);

        case 'email':
            reg = /^\S+@\w+(\.\w+)+\.?$/;
            return reg.test(value);

        case 'pstring' :
            if ($('#log').val() == 0) {
                return true;
            } else {
                reg = /\w+/;
                return reg.test(value);
            }

        default :
            return false;
    }
}


/**
 * Konstruktor głównej klasy aplikacji wyszukiwarki.
 */
function Search(index, payment_index)
{
    var t = this;
    var background = "#666"; // kolor podkreślenia brakujących pól
    var border = "1px solid #FF0000";
    var submit = 1;
    var show = 0;
    var Gzoom = 11;
    var index = index ? index : 'ajaxproxy.php';
    var hideduringwaitig = true;

    // Kod animacji wskaźnika postępu ładowania AJAX
    var loadIndicator4AJAX = '<div class="waitcircle" style="text-align: center; vertical-align: middle"><img class="ajaxloaderimg" style="display: block; margin-left: auto; margin-right: auto; padding-top: 10px; padding-bottom: 10px" src="' + base_url + 'images/ajaxloader.gif"></div>';

    // Funkcje obsługi akcji formularzy

	this.reloadPage = function(listOffset, sortColumn, sortOrder)
	{
	    window.scroll(0, 0);
	    t._backToStep(1, false);

	    showAJAXLoadIndicator(translation_please_wait);

	    var addr = index + '&step=2&offset=' + listOffset + '&sort=' + sortColumn + '&order=' + sortOrder + '&currencyid=' + selected_currencyid +
	    '&searchqueryid=' + $('#searchqueryid').val() + '&searchexecid=' + $('#searchexecid').val() + '&' + extra_params;

	    // Ukrycie formularza wyszukiwarki
	    if (hide_search_form) {
	        $('#BV_search_machine').hide();
	    }

	    // Ukrycie panelu logowania
	    if (hide_loginbox) {
	        $('#BV_loginbox').hide();
	    }

	    $('#step1').load(addr, { limit: 50 }, function(){
	        hideAJAXLoadIndicator();
	        searchEnabled = true;
	        
	        $('#BVAction_backlist_button').click(function(){
	            // Wyświetlenie formularza wyszukiwarki
	            if (hide_search_form) {
	                $('#BV_search_machine').show();
	            }
	            
	            // Wyświetlenie panelu logowania
	            if (hide_loginbox) {
	                $('#BV_loginbox').show();
	            }
	            
	            t._backToStep(1, true);
	        });
	        
	        // init mapek
	        t._mapInit();
	
	        // obsługa wyników
	        t._getResults();
	
	        searchEnabled = true;
	    });
	}


    this.reloadReservations = function(listOffset, sortColumn, sortOrder)
    {
		showAJAXLoadIndicator(translation_please_wait);
        $('#basketlist').load(index + '&step=14&sid=' + session_id + '&offset=' + listOffset + '&sort=' + sortColumn + '&order=' + sortOrder + '&' + extra_params, {limit: 25}, function() {
            // Sprawdzanie, czy logowanie było poprawne
            if ($('#userverification').attr('value') != '0') {
                t.loadUserPanel();
            } else {
                $('#login_alert').html(translation_bad_login);
            }

            hideAJAXLoadIndicator();

            $('#BVAction_backlist_button').click(function() {
                history.go(0);
            });

            $('#BV_loginbox').fadeIn('slow');

            $('.nextbasket').click(function() {
                $('#basketinfo').html('');

                $('#basketlist').fadeOut('slow', function() {
                    $('#basketinfo').fadeIn('slow');
                });

                $('#basketinfo').load(index + '&step=15&bid=' + $(this).attr('id') + '&' + extra_params, {limit: 25}, function() {
                    // prosby do operatora
                    $('#BVAction_sendcancelask').click(function() {
                        t.askform();
                    });

                    $('#BVAction_backtolistbasket').click(function() {
                        $('#basketinfo').fadeOut('slow', function() {
                            $('#basketlist').fadeIn('slow');
                        });
                    });

                    $('#BVAction_printflow').click(function() {
                        var flowaddress = $('#flowaddress').val() + '&hash=' + joinHash(hash) + '&' + extra_params;
                        window.open(flowaddress, null, "height=480,width=600,status=no,toolbar=no,menubar=no,location=no");
                    });
                });
            });

	        $('.change_Page').click(function() {
                curReservPage = $(this).attr('offset');
                t.reloadReservations(curReservPage, curReservSortField, curReservOrder);
            });
        });		
    }


    /**
     * Wydruk przelewu.
     */
    this.printForOverflow = function()
    {
        var getdata = [];
        if (location.search.length > 1) {
            var ls = location.search.substring(1);

            var nv = ls.split("=");

            if (nv[0] == 'bid' && nv[1]) {
                $('#overflow').load(index + '&step=5&bid=' + nv[1] + '&hash=' + joinHash(hash) + '&' + extra_params, {limit: 25}, function(){});
            }
        }
    }


    this.buildToBasketList = function()
    {
        $('#baskets').remove();
        $('#basketlist').remove();
        $('#basketinfo').remove();
        $('#results').remove();
        $('#BV_content').html('<div id="results"><div id="baskets"></div><div id="basketlist"></div><div id="basketinfo"></div><div id="userdatachange"></div><div id="userdatachangepassword"></div></div> ');
    }


    /*
     * Zalogowanie użytkownika.
     */
    this.loginUser = function()
    {
        var postData = {};

        regs = /\w+/;
        if (!regs.test(b_log) || !regs.test(b_pas)) {
            alert(translation_correct_missing_fields);
            return;
        }

        indexElements = index.split('?');
        loginURL = indexElements[0];

        postData['hash'] = indexElements[1].replace('hash=', '');
        postData['step'] = '58';
        postData['login'] = b_log;
        postData['password'] = b_pas;

        extraParams = extra_params.split('&');

        for (i = 0; i < extraParams.length; i++) {
            param = extraParams[i].split('=');
            postData[param[0]] = param[1];
        }

        $.ajax({
			url: loginURL,
			data: postData,
			dataType: 'html',
			async: false,
			success: function(resp) {
                loginResult = resp.split('|');
                if (loginResult[0].length == 32) {
                    auth_user = true;
                    is_agent = (loginResult[1] == 'T');
                    session_id = loginResult[0];
                } else {
                    auth_user = false;
                    is_agent = false;
                    session_id = null;
                }

                $('#BVInput_login').val('');
                $('#BVInput_password').val('');
            }
		});
    }


    /*
     * Wylogowanie użytkownika.
     */
    this.logoutUser = function()
	{
		var postData = {};

        indexElements = index.split('?');
        loginURL = indexElements[0];

        postData['hash'] = indexElements[1].replace('hash=', '');
        postData['step'] = '59';
        postData['sid'] = session_id;

        extraParams = extra_params.split('&');

        for (i = 0; i < extraParams.length; i++) {
            param = extraParams[i].split('=');
            postData[param[0]] = param[1];
        }

        $.ajax({
            url: loginURL,
            data: postData,
            dataType: 'html',
            async: false,
            success: function(resp) {
                auth_user = false;
                is_agent = false;
                session_id = null;
				sid = '';

                $('#BVInput_login').val('');
                $('#BVInput_password').val('');
            }
        });
	}


    /*
     * Sprawdzenie zalogowanego użytkownika.
     */
    this.checkLoggedUser = function()
	{
        var postData = {};

        indexElements = index.split('?');
        loginURL = indexElements[0];

        postData['hash'] = indexElements[1].replace('hash=', '');
        postData['step'] = '60';
        postData['sid'] = session_id;

        extraParams = extra_params.split('&');

        for (i = 0; i < extraParams.length; i++) {
            param = extraParams[i].split('=');
            postData[param[0]] = param[1];
        }

        $.ajax({
            url: loginURL,
            data: postData,
            dataType: 'html',
            async: false,
            success: function(resp) {
                if (resp != 'ERROR') {
                    auth_user = true;
                    is_agent = (resp == 'T');
                } else {
                    auth_user = false;
                    is_agent = false;
                    session_id = null;
                }

                $('#BVInput_login').val('');
                $('#BVInput_password').val('');
            }
        });		
	}


    this.loadUserPanel = function()
	{
         $('#BV_loginbox').load(index + '&step=16&hide=1&sid=' + session_id + '&' + extra_params, {limit: 25}, function() {
            auth_user = true;

            // Skojarzenie funkcji obsługi akcji z elementami o podanym ID

            $('#BVAction_reserv_list').click(function(){
                t.showListBasket();
            });


            $('#BVAction_cancel_reserv').click(function() {
                $('#basketlist').fadeOut('slow');
                $('#userdatachange').fadeOut('slow');
                $('#basketinfo').fadeIn('slow');
                t.askform();
            });


            $('#BVAction_user_data').click(function() {
                $('#basketlist').fadeOut('slow');
                $('#basketinfo').fadeOut('slow');
                $('#userdatachange').fadeIn('slow');
                t.showUserData();
            });


            $('#BVAction_logout').click(function() {
                t.logoutUser();
                location = location.protocol + '//' + location.host + location.pathname;
            });


            $('#BVAction_newsletter_change0').click(function() {
                var newsletter_data = {};
                newsletter_data['step']= 26;
                newsletter_data['email']= b_log;
                $.get(index + '?' + extra_params, newsletter_data, function(ns) {
                    alert(translation_removed_from_newsletter);
                    t.showListBasket();
                });
            });


            $('#BVAction_newsletter_change1').click(function() {
                var newsletter_data = {};
                newsletter_data['step']= 27;
                newsletter_data['email']= b_log;

                $.get(index + '?' + extra_params, newsletter_data, function(ns) {
                    alert(translation_added2newsletter);
                    t.showListBasket();
                });
            });
         });		
	}


    this.reloadBuyForm = function()
	{
        // Lista serwisow a dokladnie searchqueryresults
        var i;
        var services = '&services=';

        for (i in searchresultids) {
            if (searchresultids[i] > 0 && i > 0) {
                services += ',' + i + '_' + searchresultids[i];
            }
        }

        var addr = '&step=3' + services + "&placeid=" + $('#placeid').attr('value');
        // Doklejamy informację o zalogowanym agencie
        //if (is_agent) addr += '&al=' + b_log + '&ap=' + b_pas + '&agent=1';
        // Doklejamy informację o zalogowanym użytkowniku (ID sesji)
        if (auth_user) addr += '&sid=' + session_id + '&upsrv=1';

        // Przejście do formularza rezerwacji
        t._buyformular(addr);		
	}


    this.showListBasket = function()
    {
        if (!auth_user) {
			alert(translation_bad_login);
			return;
		}

        t.buildToBasketList();
        $('#BV_loginbox').fadeOut('slow');
		t.reloadReservations(curReservPage, curReservSortField, curReservOrder);
    }


    this.askform = function()
    {
        var pr = {};

        showAJAXLoadIndicator(translation_please_wait);

        $('#basketinfo').load(index + '&step=22&bid=' + $('#bidhash').val() + '&' + extra_params, {limit: 25}, function() {
            hideAJAXLoadIndicator();

			if (auth_user) {
                $('#BVAction_backtolistbasket').click(function() {
                    t.showListBasket();
                });
            } else {
                $('#BVAction_backtolistbasket').hide();
            }

            $('#BVAction_asksend').click(function() {
                showAJAXLoadIndicator(translation_please_wait);

                pr['bno'] = $('[name=basketno]').val();
                pr['asktype'] = $('[name=asktype]:checked').val()
                pr['text'] = $('[name=asktext]').val();

                $.post(index + '&step=23' + '&sid=' + session_id + '&' + extra_params, pr, function(obj) {
                    hideAJAXLoadIndicator();

                    if (obj == 'OK') {
                        if (auth_user) {
                            if (confirm(translation_msg_sent_ret2list)) {
                                $('#BVAction_backtolistbasket').click();
                            }
                        } else {
                            alert(translation_msg_sent_opcontact);
                        }
                    } else {
                        alert(translation_send_error);
                    }
                });
            });
        });
    }

    // Koszyki, szczegóły rezerwacji
    this.showBasket = function() {
        if (hideduringwaitig) $('#BV_loginbox').html(loadIndicator4AJAX);

        if (sid != '') {
            session_id = sid;
            t.checkLoggedUser();
			if (auth_user) {
				t.showListBasket();
				return;
			}
        }

        $('#BV_loginbox').load(index + '&step=13' + '&' + extra_params, {limit: 25}, function() {
            // Formularz załadowany

            // Skojarzenie akcji z elementami formularza

            $('#BVAction_login').click(function() {
                b_log = $('#BVInput_login').val();
                b_pas = $('#BVInput_password').val();                
				t.loginUser();
				t.showListBasket();
            });


            $('#BVInput_password').keydown(function(e) {
                if (e.keyCode == 13) {
                    b_log = $('#BVInput_login').val();
                    b_pas = $('#BVInput_password').val();                    
					t.loginUser();
					t.showListBasket();
                }
            });


            $('#BVInput_login').keydown(function(e) {
                if (e.keyCode == 13 && $('#BVInput_password').val()) {
                    b_log = $('#BVInput_login').val();
                    b_pas = $('#BVInput_password').val();                    
					t.loginUser();
					t.showListBasket();
                }
            });


            $('.cancel_basket_loginbox').click(function() {
                t.buildToBasketList();
                t.askform();
                hideAJAXLoadIndicator();
            });
        });
    }


    // Dane użytkownika do modyfikacji
    this.showUserData = function(){
        var bb_log = '&login=' + b_log;
        var bb_pas = '&password=' + b_pas;

        showAJAXLoadIndicator(translation_please_wait);
        t.buildToBasketList();

        $('#userdatachange').load(index + '&step=37&' + bb_log + bb_pas + '&' + extra_params, {limit: 25}, function() {
            hideAJAXLoadIndicator();

            $('#BVAction_backtolistbasket').click(function() {
                t.showListBasket();
            });


            $('#BVAction_changeuserdata').click(function() {
                showAJAXLoadIndicator(translation_please_wait);
                var submit = 0;
                var data_to_send = {};

                $('.data').each(function() {
                    if (validate($(this).val(), $(this).attr('data'), $('#invoice').val(), $(this).attr('name'))) {
                        data_to_send[$(this).attr('name')] = $(this).val();
                        $(this).css("border",'1px solid #7F9DB9');
                    } else {
                        // Jest coś źle
                        submit++;
                        $(this).css("border", "1px solid #FF0000");
                    }
                });

                if (submit > 0) {
                    hideAJAXLoadIndicator();
                    alert(translation_check_fields);
                } else {
                    $.post(index + '&step=39&' + bb_log + bb_pas + '&' + extra_params, data_to_send, function(obj) {
                        hideAJAXLoadIndicator();
                        if (obj == 'OK') {
                            alert(translation_data_saved);
                            $('#BVAction_backtolistbasket').click();
                        }
                        else {
                            alert(translation_send_error);
                        }
                    });
                }
            });


            $('#BVAction_changepassword').click(function() {
                showAJAXLoadIndicator(translation_please_wait);

                $('#userdatachange').fadeOut(function() {
                    $('#userdatachangepassword').load(index + '&step=44&fase=0' + '&' + extra_params, {limit: 25}, function() {
                        hideAJAXLoadIndicator();

                        $('#BVAction_changepasswordfinal').click(function() {
                            var submit2 = 0;
                            var data_to_send = {};

                            $('.data2').each(function() {
                                if ($(this).val() !='')
                                {
                                    data_to_send[$(this).attr('name')] = $(this).val();
                                    $(this).css("border",'1px solid #7F9DB9');
                                }else{
                                // jest cos zle
                                    submit2++;
                                    $(this).css("border","1px solid #FF0000");
                                }
                            });
                            if($('#newpassword').val() != $('#newpassword2').val()){
                                $('#newpassword').css("border","1px solid #FF0000");
                                $('#newpassword2').css("border","1px solid #FF0000");
                                submit2 = 100;
                            }
                            if (submit2 > 0) {
                                hideAJAXLoadIndicator();
                                if(submit2 == 100){
                                    alert(translation_enter_valid_passwords);
                                }else{
                                    alert(translation_check_fields);
                                }
                            } else {
                                $.post(index + '&step=44&fase=1' + bb_log + '&' + extra_params, data_to_send, function(obj) {
                                    hideAJAXLoadIndicator();
                                    if (obj == 'OK') {
                                        alert(translation_data_saved);
                                        b_pas = $('#newpassword').val();
                                        $('#BVAction_backtoprofile').click();
                                    } else if (obj == 'PASSWORD'){
                                        alert(translation_enter_valid_old_pwd);
                                    } else {
                                        alert(translation_send_error);
                                    }
                                });
                            }
                        });


                        $('#BVAction_backtoprofile').click(function() {
                            t.showUserData();
                        });
                    });
                });
            });
        });
    }


    this.showLowestPrices = function() {
        showAJAXLoadIndicator(translation_please_wait);

        $('#BV_lowest_prices').load(index + '&step=61&currencyid=' + $('#currencyid').val() + '&' + extra_params, {limit: 25}, function() {
            hideAJAXLoadIndicator();
        });
	}


    this.showPromoList = function() {
        showAJAXLoadIndicator(translation_please_wait);

        $('#BV_promo_list').load(index + '&step=62&' + extra_params, {limit: 25}, function() {
            hideAJAXLoadIndicator();
        });
    }


    //------------------------------------------------------------------------------
    // WYSZUKIWARKA POKOJÓW
    //------------------------------------------------------------------------------

    this.firstSearch = function()
    {
        var start_now = true;
    }


    // Gdy manipulujemy datami, dbamy o złe terminy
    this._calendarSetCheckoutRange = function() {
        // checkin i checkout - oiekty tworzone w template/search_form.html
        if (checkin.get() > checkout.get()) {
            // funkcja Date.parseDate jest stworzona w kalendarzyku jscalendar
            var d = Date.parseDate( checkin.get(), "%Y-%m-%d" );
            var d1 = Date.parseDate( checkout.get(), "%Y-%m-%d" );
            d.setDate( d.getDate() + 1 );
            checkout.set( d.print( "%Y-%m-%d" ) );
        }
    }


    // Kliknięcie na przycik REZERWUJĘ, ostatni krok
    this._pay = function()
    {
        var data_send = {};
        var data_pack = '';
        submit = 0;

        if (!$('input#agree:checked').val()) {
            submit++;
        }

        $('.data').each(function() {
            if (validate($(this).val(), $(this).attr('data'), $('#invoice').val(), $(this).attr('name'))) {
                data_send[$(this).attr('name')] = $(this).val();
                $(this).css('border', '1px solid #7F9DB9');
            } else {
                // Jest coś źle
                submit++;
                $(this).css('border', '1px solid #FF0000');
            }
        });

        // Komponenty dodatkowe
		extra_components = '';
        $('.BVAction_compCheckbox').each(function() {
			if ($(this).is(':checked')) {
				if (extra_components != '') extra_components += ',';
				extra_components += $(this).attr('comp_id') + 'x' + $(this).attr('amount');
			}
        });
		data_send['excmps'] = extra_components;

        if (submit == 0) {
            t._payment(data_send);
        } else {
            alert(translation_check_fields_and_agree);
        }

        return data_send;
    }

    // Zapis koszyka i płatności
    this._payment = function(data_send)
    {
		var payment_type = $('input[name=payment_type]:checked').val();

        if (is_agent && deferred_payment) {
			// Jeśli agent ma płatność odroczoną nie dokonuje zapłaty
			payment_type = -1;
		}

        var country_payment_type = $('#country_payment_type').val();
        var sids = '&servicesids=' + $('#serviceids').val();
        var addr = '&step=4' + sids;

        searchEnabled = false;
		window.scroll(0, 0);
        showAJAXLoadIndicator(translation_please_wait);

        $.get(index + addr + '&payment_type=' + payment_type + '&' + extra_params, data_send, function(bid) {
            hideAJAXLoadIndicator();

            if (isNaN(parseFloat(bid))) {
                if (confirm(translation_booking_error)) {
                    window.open(chg_user_pwd_addr);
                } else {
                    $('#BVAction_buy_login').click();
                }

                searchEnabled = true;

                return;
            }

            var href = payment_index + "?basketid=" + bid + "&payment_type=" + payment_type + "&cpay=" + country_payment_type + "&sid=" + session_id;

            // dla platnosci przelewem, bez przechodzenia na DotPay
            if (payment_type != -1 && payment_type != 99) {
				// DotPay, eCard
				if (payment_type == 3) {
					// eCard
					ecard_rqid = getAJAX(index + '&step=55&basketid=' + bid + '&payment_type=' + payment_type + '&cpay=' + country_payment_type + '&paymenttype=TRANSFERS');
					if (ecard_rqid == 'ERROR!') {
						alert('Payment system error!');
						return;
					}
					href += '&requestid=' + ecard_rqid;
				}

                window.location = href;
            } else {
				searchEnabled = false;
                showAJAXLoadIndicator(translation_please_wait);

                // Doklejamy informację o zalogowanym agencie
                //if (is_agent) agent_data = '&al=' + b_log + '&ap=' + b_pas + '&agent=1'; else agent_data = '';
                // Doklejamy informację o zalogowanym użytkowniku (ID sesji)
                if (auth_user) agent_data = '&sid=' + session_id; else agent_data = '';

                $('#step3').load(index + '&step=6&bid=' + bid + "&payment_type=" + payment_type + agent_data + '&' + extra_params,{}, function() {
                    hideAJAXLoadIndicator();
                    searchEnabled = true;
                    // Przekierowanie po wydrukowaniu formularza przelewu
                    $('#BVAction_end_reservation').click(function() {
                        window.location = redir_payform_print + '?sid=' + session_id;
                    });
                }); // end - step3
            }
        });
   }


   // Formularz rezerwacji, akcje na formularzu
   this._buyformular = function(addr)
   {
        searchEnabled = false;
        t._backToStep(3, false);

        showAJAXLoadIndicator(translation_please_wait);

        $('#step3').load(index + addr + '&' + extra_params, {limit : 120}, function() {
            window.scroll(0, 0);
            hideAJAXLoadIndicator();
			searchEnabled = true;

	        // Przycisk wstecz
	        $('#BuyBack').mouseover(function() {
	            $('#BuyBack').toggleClass('BV_BackBtn_hover');
	            $('#BuyBack_l').toggleClass('BV_BackBtnLeft_hover');
	            $('#BuyBack_m').toggleClass('BV_BackBtnMiddle_hover');
	            $('#BuyBack_r').toggleClass('BV_BackBtnRight_hover');
	        }).mouseout(function() {
	            $('#BuyBack').toggleClass('BV_BackBtn_hover');
	            $('#BuyBack_l').toggleClass('BV_BackBtnLeft_hover');
	            $('#BuyBack_m').toggleClass('BV_BackBtnMiddle_hover');
	            $('#BuyBack_r').toggleClass('BV_BackBtnRight_hover');         
	        });

            // Jeśli mamy już hasło i login
            $('#BVAction_buy_login').click(function() {
                /*$('#registred').slideToggle(function() {
                    $('#newuser').slideToggle();
                });*/
				registeredElement = document.getElementById('registred');
				newuserElement = document.getElementById('newuser');
				if (registeredElement.style.display != 'none') {
					registeredElement.style.display = 'none';
					newuserElement.style.display = 'block';
				} else {
                    registeredElement.style.display = 'block';
                    newuserElement.style.display = 'none';					
				}

                $('#log').val($('#log').val() > 0 ? 0 : 1);
            });

            // Prośba o fakturę, podajemy dane firmy
            $('#wantinvoice').click(function() {
                $('#invoiceinfo').slideToggle();
                $('#invoice').val($('#invoice').val() > 0 ? 0 : 1)  ;
            });

            // Jeśli jesteśmy zalogowani
            if (b_log && b_pas) {
				$('#BVAction_login2').hide();
                $('#BVInput_login2').val(b_log);
                $('#BVInput_password2').val(b_pas);
                $('#BVAction_buy_login').click();				
            } else {
				$('#BVAction_login2').show();
			}

            $('#BVAction_login2').click(function() {
                b_log = $('#BVInput_login2').val();
                b_pas = $('#BVInput_password2').val();                
                t.loginUser();
                if (auth_user) {
					t.loadUserPanel();
					t.reloadBuyForm();
				} else {
					if (b_log == '' && b_pas == '') alert(translation_bad_login);
				}
            });

            // przejscie do platnosci, ostatnia akcja (krok4)
            $('#BVAction_pay').click(function() {
                t._pay();
				location = client_base_url + '#payment';
            });

            $('#BVAction_hotel_back').click(function() {
                t._backToStep(2, true);
            });

			// Aktualizacja ceny rezerwacji przy wyborze komponentów dodatkowych
			$('.BVAction_compCheckbox').click(function() {
				comp_id = $(this).attr('comp_id');
				roomid = $(this).attr('roomid');

				totalPriceVal = parseFloat($('#price2pay').html().replace(' ', ''));
				bookingVal = parseFloat($('#booking_value').html().replace(' ', ''));
				priceVal = parseFloat($('#bcompv_' + roomid + '_' + comp_id).val());

				if ($(this).is(':checked')) {
					totalPriceVal += priceVal;
					bookingVal += priceVal;
					$('#bcprice_' + roomid + '_' + comp_id).show();
					$('#bctprice_' + roomid + '_' + comp_id).show();
				} else {
					totalPriceVal -= priceVal;
					bookingVal -= priceVal;
                    $('#bcprice_' + roomid + '_' + comp_id).hide();
                    $('#bctprice_' + roomid + '_' + comp_id).hide();					
				}

				$('#price2pay').html(formatMoney(totalPriceVal, '', ' ', ','));
				$('#booking_value').html(formatMoney(bookingVal, '', ' ', ','));
			});
        });
    }

    // Obsługa formularza, przycisku aktywującego szczegóły obiektu
    this._getResults = function()
    {
        $('.photo_lightbox').lightBox();

        $('.show_object').click(function() {
			window.scroll(0, 0);
            t._backToStep(2, false);

            showAJAXLoadIndicator(translation_please_wait);

            var addr = index + '&step=2&placeid=' + $(this).attr('id') +
                      '&searchqueryid=' + $('#searchqueryid').val() +
                      '&searchexecid=' + $('#searchexecid').val() + '&currencyid=' + $('#currencyid').val() + '&' + extra_params;

            // Ukrycie formularza wyszukiwarki
            if (hide_search_form) {
                $('#BV_search_machine').hide();
            }

            // Ukrycie panelu logowania
            if (hide_loginbox) {
                $('#BV_loginbox').hide();
            }

            $('#step2').load(addr, {limit: 50}, function() {
                hideAJAXLoadIndicator();
                searchEnabled = true;

                $('#BVAction_backlist_button').click(function() {
                    // Wyświetlenie formularza wyszukiwarki
                    if (hide_search_form) {
                        $('#BV_search_machine').show();
                    }

                    // Wyświetlenie panelu logowania
                    if (hide_loginbox) {
                        $('#BV_loginbox').show();
                    }

                    t._backToStep(1, true);
                });

                // Obsługa hotelu
                t._hotel();
            });

			location = client_base_url + '#details';
        });

        $('.change_Page').click(function() {
			curListPage = $(this).attr('offset');
			t.reloadPage(curListPage, curSortField, curOrder);
        });


		$('.header_placename').click(function() {
			if (curSortField == 'name') {
				if (curOrder == 'asc') curOrder = 'desc'; else curOrder = 'asc'; 
			} else {
				curOrder = 'asc';
			}
			t.reloadPage(curListPage, 'name', curOrder);
        });


        $('.header_location').click(function() {
            /*if (curSortField == 'location') {
                if (curOrder == 'asc') curOrder = 'desc'; else curOrder = 'asc'; 
            } else {
                curOrder = 'asc';
            }
			t.reloadPage(curListPage, 'location', curOrder);*/
        });


        $('.header_price').click(function() {
            if (curSortField == 'price') {
                if (curOrder == 'asc') curOrder = 'desc'; else curOrder = 'asc'; 
            } else {
                curOrder = 'asc';
            }			
			t.reloadPage(curListPage, 'price', curOrder);
        });		
    }


    // Konkretny hotel
    this._hotel = function()
    {
        searchresultids = t._hotel_actions();

        // Zliczamy cenę jeśli zaznaczono ilość pokoi
        var sum = 0;

        $('.al').each(function() {
            var tmp_sum = parseFloat($(this).attr('price') * $(this).val());
            sum = parseFloat(tmp_sum) + parseFloat(sum);
            searchresultids[$(this).attr('searchresultid')] = $(this).val();

            avail_allotment = parseInt($(this).attr('avail_allotment'));

            // Jeśli allotment zerowy lub przekroczono jego wartość to rezerwacja "na zapytanie"
			if (!avail_allotment || $(this).val() > avail_allotment) {
				$('#msg_' + $(this).attr('id')).show();
			} else {
				$('#msg_' + $(this).attr('id')).hide();
			}
        });

        // Uaktualnienie sumy kosztów wybranych pokojów
        $('#sum').html(formatMoney(sum, '', ' ', ',') + ' ');
        $('#submithid').val(sum);

        // Dokonanie rezerwacji, przejście do formularza z danymi (krok 3)
        $('#BVAction_buy').click(function() {
            if ($('#submithid').val() <= 0) {
            // TODO : jakis ciekawszy komunikat
                alert(translation_error_1room);
            } else {
                // Lista serwisow a dokladnie searchqueryresults
                var i;
                var services = '&services=';

                for (i in searchresultids) {
                    if (searchresultids[i] > 0 && i > 0) {
                        services += ',' + i + '_' + searchresultids[i];
                    }
                }

                var addr = '&step=3' + services + "&placeid=" + $('#placeid').attr('value');
				// Doklejamy informację o zalogowanym agencie
                //if (is_agent) addr += '&al=' + b_log + '&ap=' + b_pas + '&agent=1';
                // Doklejamy informację o zalogowanym użytkowniku (ID sesji)
                if (auth_user) addr += '&sid=' + session_id;

                // Przejście do formularza rezerwacji
                t._buyformular(addr);
            }

			location = client_base_url + '#booking';
        });
    }


    // Akcje w wynikach wyszukiwania
    this._hotel_actions = function()
    {
        var searchresultids = new Array();

        $('#photos a').lightBox();

        // Skojarzenie akcji po wczytaniu opisu

        // Przycisk wstecz
		$('#HotelBack').mouseover(function() {
			$('#HotelBack').toggleClass('BV_BackBtn_hover');
			$('#HotelBack_l').toggleClass('BV_BackBtnLeft_hover');
			$('#HotelBack_m').toggleClass('BV_BackBtnMiddle_hover');
			$('#HotelBack_r').toggleClass('BV_BackBtnRight_hover');
		}).mouseout(function() {
            $('#HotelBack').toggleClass('BV_BackBtn_hover');
            $('#HotelBack_l').toggleClass('BV_BackBtnLeft_hover');
            $('#HotelBack_m').toggleClass('BV_BackBtnMiddle_hover');
            $('#HotelBack_r').toggleClass('BV_BackBtnRight_hover');			
		});

        if (use_gmaps) {
			if (GBrowserIsCompatible()) {
				GUnload();
				var map = new GMap2(document.getElementById('maphotel'));
				map.setCenter(new GLatLng($('#maphotel').attr('glat'), $('#maphotel').attr('glng')), 11);
				map.addControl(new GLargeMapControl());
				
				var point = new GLatLng($('#maphotel').attr('glat'), $('#maphotel').attr('glng'));
				var marker = new GMarker(point);
				map.addOverlay(marker);
			}
		}

        // Zmiana jakiegoś selecta z allotmentem powoduje zmianę ceny
        $('.al').change(function() {
            var sum = 0;
			var clickedElemId = $(this).attr('id');

            // Wyłączamy ewentualne wybory tego samego pokoju z innej oferty (tylko jedna oferta na pokój!)
            cur_id = clickedElemId.split('_');             
            base_id = cur_id[0];
            offer_id = cur_id[1];
            otherOffers = $("select[id^='" + base_id + "']");

            for (i = 0; i < otherOffers.length; i++) {
                id_array = otherOffers[i].id.split('_');
				if (id_array[1] != offer_id) {
					// Zerujemy allotment wszystkim pokojom tego typu z innych ofert i dodajemy go do aktualnie klikniętej oferty 
					$('#' + clickedElemId).val(parseInt($('#' + clickedElemId).val()) + parseInt($('#' + otherOffers[i].id).val()));  
				    $('#' + otherOffers[i].id).val(0);
				}
            }

            $('.al').each(function() {
                var tmp_sum  =  parseFloat($(this).attr('price') * $(this).val());
                sum = parseFloat(tmp_sum) + parseFloat(sum);
                searchresultids[$(this).attr('searchresultid')] = $(this).val();

	            avail_allotment = parseInt($(this).attr('avail_allotment'));

                // Jeśli allotment zerowy lub przekroczono jego wartość to rezerwacja "na zapytanie"
	            if (!avail_allotment || $(this).val() > avail_allotment) {
	                $('#msg_' + $(this).attr('id')).show();
	            } else {
	                $('#msg_' + $(this).attr('id')).hide();
	            }
            });

            $('#sum').html(formatMoney(sum, '', ' ', ',') + ' ');
            $('#submithid').val(sum);
        });

        return searchresultids;
    }


    // Akcja po kliknięciu mapki w wynikach
    this._mapInit = function()
    {
        $('.mapmarker').click(function() {
            if (!use_gmaps) return;

            is_map = true;
            showGoogleMap(0);

            $('#bookingsearchformContainer').hide();

            var Glat = $(this).attr('glat');
            var Glng = $(this).attr('glng');

            if (GBrowserIsCompatible()) {
                var map = new GMap(document.getElementById('mapcontent'));
                var point = new GLatLng(Glat, Glng);
                map.setCenter(point, 11);
                map.addControl(new GLargeMapControl());

                var marker = new GMarker(point);
                map.addOverlay(marker);
            }
        });
    }

    // Obsługa formularza wyszukiwania

    this._formular_actions = function()
    {
        // wyposazenie dodatkowe
        $('#extras').hide();
        /*  $('#more').click(function(){
            $('#extras').slideToggle('slow');
        });*/

        $('#more').click(function(){
            $('#extras').toggle();
        });

        // Lista pokojów, typy + rodzaje
        $('.roomselect').hide();

        // Dodajemy rodzaj pokoju
        $('#add').click(function() {
            var ct =  parseInt($('#cr').val());

            $('#cr').val(ct == 3 ? 3 : ++ct);

            $('.roomtype_record').each(function() {
                if ($(this).attr('nr') <= ct) {
                    $(this).show('slow');
                }
            });

            // Pokazuje się przycisk odejmowania pokoju
            $('#del').show('slow');

            if ($('#cr').val() > 2) {
                $('#add').hide('slow');
            }
        });


        // Usuwamy wybór pokoju
        $('#del').click(function() {
            var ct =  parseInt($('#cr').val());

            $('#cr').val(ct == 1 ? 1 : --ct);

            $('.roomtype_record').each(function() {
                if ($(this).attr('nr') > ct) {
                    $('#numofrooms'+$(this).attr('nr')).val(0);
                    $(this).hide('slow');
                }
            });

            if ($('#cr').val() < 2) {
                $('#del').hide('slow');
            }

            if ($('#cr').val() < 3) {
                $('#add').show('slow');
            }
        });


        // Kontrola wpisywanej daty, przedziałów
        $('select.Ym , select.d').change(function(){
            t._calendarSetCheckoutRange();
        });
    }


    /**
     * Pobranie parametrow wyszukiwania.
     *
     * @return adres url z paramertami
     */
    this._get_params = function()
    {
        var day_in = $('#checkindate_d').val() > 9 ? $('#checkindate_d').val() : '0' + $('#checkindate_d').val();
        var day_out = $('#checkoutdate_d').val() > 9 ? $('#checkoutdate_d').val() : '0' + $('#checkoutdate_d').val();

        // doklejamy parametry wywołania ajaxproxy.php
        var params = '';

        params += '&checkindate=' + $('#checkindate_Ym').val() + '-' + day_in;
        params += '&checkoutdate=' + $('#checkoutdate_Ym').val() + '-' + day_out;

        if ($('#noresults').val() != '0') {
            params += '&roomtypeid=' + $('#roomtypeid').val();
            params += '&roomtypeid2=' + $('#roomtypeid2').val();
            params += '&roomtypeid3=' + $('#roomtypeid3').val();

            params += '&numofrooms=' + $('#numofrooms').val();
            params += '&numofrooms2=' + $('#numofrooms2').val();
            params += '&numofrooms3=' + $('#numofrooms3').val();

            params += '&placetypeid=' + $('#placetypeid').val();
            params += '&currencyid=' + $('#currencyid').val();
            params += '&countrooms=' + $('#cr').val();
            params += '&equipment=';

            if (hotel_placeid != "") params += '&place=' + hotel_placeid;

            // Składanie wyposażenia pokojów
            if ($('#more:checked').val()) {
                $('input[class=equipment]:checked').each(function() {
                    params += "," + $(this).val();
                });
                params += '&offercode=' + $('#offercode').val();
            }

            // Jeśli ktoś nie poda celu przeszukujemy cały kraj !
            if (!destination ) {
                //params += '&country=1001';
            } else {
                params += '&' + destination.type + '=' + destination.id;
            }

            var addr = index + '&step=2' + params + '&' + extra_params;
        } else {
            var addr = index + '&step=2&country=1001&noresults=1' + params + '&' + extra_params;
        }

        // Doklejamy informację o zalogowanym agencie
		//if (is_agent) addr += '&al=' + b_log + '&ap=' + b_pas + '&agent=1';
        // Doklejamy informację o zalogowanym użytkowniku (ID sesji)
        if (auth_user) addr += '&sid=' + session_id;		

		selected_currencyid = $('#currencyid').val();

        return addr;
    }

    // tworzymy elementy do wrzucania zawartosci
    this._buildAreas = function()
    {
        $('#results').remove();
        $('#baskets').remove();
        $('#basketlist').remove();
        $('#basketinfo').remove();

        $('#BV_content').html('<a name="details" id="a_details"></a><a name="booking" id="a_booking"></a><a name="payment" id="a_payment"></a><div id="results"></div>');
        $('#results').html('<div id="step1"></div><div id="step2"></div><div id="step3"></div><div id="step4"></div>');

		$('#a_details').click(function() {
			alert('Details');
		});

        $('#a_booking').click(function() {
            alert('Booking');
        });		
    }

    // Pokazuje tylko jeden wybrany krok
    // @opacity, jeśli true to znaczy że się cofamy!!

    this._backToStep = function(nr, opacity)
    {
        switch (opacity) {
            case false:
                switch (nr) {
                    case 1:
                         $('#step1').show();
                         $('#step2').hide();
                         $('#step3').hide();
                         break;

                    case 2:
                         $('#step2').show();
                         $('#step1').hide();
                         $('#step3').hide();
                         break;

                    case 3:
                         $('#step3').show();
                         $('#step2').hide();
                         $('#step1').hide();
                         break;
                }
                break;

            case true:
                switch(nr) {
                    case 1:
                         $('#step2').fadeOut(function() {
                             $('#step1').fadeIn();
                         });
                         break;

                    case 2:
                         $('#step3').fadeOut(function() {
                             $('#step2').fadeIn();
                         });
                         break;
                }
                break;
        }
    }


    /**
     * Załadowanie formularza wyszukującego.
     * Właściwa wyszukiwarka.
     */
    this.searchMachine = function() {
        // Jeśli źle zdefiniowane wartości wyszukiwania
        if (start_service != null && end_service != null) {
            if (start_service >= end_service) {
                end_service = start_service + 1;
            }
        }

        if (hideduringwaitig && !auto_search) {
            $('#BV_search_machine').html(loadIndicator4AJAX);
        }

        // Obsługa akcji
		switch (bv_action) {
			case 'voucher':
                // Wydrukowanie vouchera
                $('#BV_search_machine').load(index + '&step=56&' + extra_params, { limit: 25 }, function() {
                });
				break;

			default:
                // Akcja domyślna - wyświetlenie wyszukiwarki
				$('#BV_search_machine').load(index + '&s_s=' + start_service + '&s_e=' + end_service + '&' + extra_params, { limit: 25 }, function() {
					$('#del').hide();
					var klikWiecej = false;
					destination = '';
					var destination_obj = new DestinationAutoComplete(document.getElementById('destination_text'));
					
					if (start_now) {
						$('#BVAction_start_search').click();
					}

					t._formular_actions();

                    // Odczytujemy ewentualne parametry przekazywane przez eCard po wykonaniu transakcji
                    ECARD_paymenttype = getQueryStringParam('paymenttype');
                    ECARD_status = getQueryStringParam('status');
                    ECARD_sid = getQueryStringParam('SESSIONID');

                    if (ECARD_paymenttype == 'ECARD') {
                        // Przekierowanie z eCard - sprawdzamy status autoryzacji
                        if (ECARD_status == 'positive') {
                            $('#eCard_AUTH_OK').show();
                        } else if (ECARD_status == 'negative') {
                            $('#eCard_AUTH_FAILED').show();
                        }
                    }

					// Rozpoczęcie szukania (krok 1)
					
					$('#BVAction_start_search').click(function(){
						if (!searchEnabled) 
							return;
						
						destination_obj.check();
						searchEnabled = false;
						
						if ($('#destination_text').val() == '') {
							destination = '';
						}
						
						t._buildAreas();
						var addr = t._get_params();
						
						// Czekanie na załadowanie
						showAJAXLoadIndicator(translation_please_wait);
						
						t._backToStep(1, false);
						
						$('#step1').load(addr, function(){
							hideAJAXLoadIndicator();
							
							// init mapek
							t._mapInit();
							
							// obsługa wyników
							t._getResults();
							
							searchEnabled = true;
							
							// jezeli mamy podany hotel to klikamy w jego szczegoly
							if (klikWiecej == true) {
								var obj = null;
								$('tr.item_obj').each(function(){
									obj = $('tr.item_obj span.show_object');
									if (obj.html().toUpperCase().indexOf(hotelParam.toUpperCase()) > -1) {
										obj.click();
									}
								});
							}

							if (hotel_placeid != "") {
								$('#' + hotel_placeid).click();
							}
						});
					});
					
					// ustawiamy parametry wyszukiwarki
					if (inputParam != "" || hotelParam != "" || startDataParam != "" || endDataParam != "" || codeParam != "" || categoryParam != "" || hotel_placeid != "") {
						// dane do inputa czyli miasto lub nazwa hotelu
						if (inputParam != "") {
							$('#destination_text').val(inputParam);
						} else {
							if (hotelParam != "") {
								$('#destination_text').val(hotelParam);
								klikWiecej = true;
							}
						}

						// ustawiam date rozpoczecia uslugi
						if (startDataParam != "") {
							var data1 = startDataParam.split("!");
							// ustawiam dzien
							$("#checkindate_d").ready(function(){
								$("#checkindate_d option").each(function(){
									if ($(this).val().indexOf(data1[0]) == 0) 
										$(this).attr("selected", "selected");
								});
							});
							// ustawiam miesiac
							$("#checkindate_Ym").ready(function(){
								$("#checkindate_Ym option").each(function(){
									if ($(this).val().indexOf(data1[2] + "-" + data1[1]) == 0) 
										$(this).attr("selected", "selected");
								});
							});
						}
						
						// ustawiam date zakonczenia uslugi
						if (endDataParam != "") {
							var data2 = endDataParam.split("!");
							// ustawiam dzien
							$("#checkoutdate_d").ready(function(){
								$("#checkoutdate_d option").each(function(){
									if ($(this).val().indexOf(data2[0]) == 0) 
										$(this).attr("selected", "selected");
								});
							});
							// ustawiam miesiac
							$("#checkoutdate_Ym").ready(function(){
								$("#checkoutdate_Ym option").each(function(){
									if ($(this).val().indexOf(data2[2] + "-" + data2[1]) == 0) 
										$(this).attr("selected", "selected");
								});
							});
						}
						// ustawiam kod promocyjny
						if (codeParam != "") {
							$('#offercode').val(codeParam);
						}
						// ustawiam kategorie
						if (categoryParam != "") {
							$('#placetypeid').ready(function(){
								$("#placetypeid option:contains(" + categoryParam + ")").attr("selected", "selected");
							});
						}
						
						if (hotel_placeid != "") {
							$('#BVAction_start_search').click();
						}

						params_present = true;
						destination_obj.asp = true;
					} else  if (auto_search == true) {
						// Bezpośrednie uruchomienie wyszukiwania zaraz po załadowaniu strony
						$('#BVAction_start_search').click();
					}

					/*t.showLowestPrices();
					t.showPromoList();*/
				});
		}
    }
}

//------------------------------------------------------------------------------
// FUNKCJE WYSZUKIWARKI (automatyczne podpowiadanie obiektów (państw, regionów, miast, hoteli))
//------------------------------------------------------------------------------

/*******************************************************************************
    @Author     Antoni Jakubiak <a.jakubiak@synerway.pl>


    @Description
            Wyszukiwarka docelowych miejsc pobytu.

            Wymaga: cms/external/cdajax/cdajax.js

*******************************************************************************/

/**
 * Utworzenie elementu automatycznej listy
 */
function DestinationAutoComplete( iInputElement )   {
    /**
     * Prefix, identyfikator tworzonych elementow
     */
    this.idPrefix = 'destinationAutoCompleteElement_';

    /**
     * element, ktory nasluchujemy
     */
    this.inputElement = iInputElement;//document.getElementById('destination_text');
    /**
     * Adres URL serwera
     */
    //this.rootUrl = iRootUrl ? iRootUrl : "";
    /**
     * Wlaczenie mapy, po wyborze punktu centrujemy mape ponownie na wskazany punkt,
     * uwaga, parametr odwrotny do inicjacji, domyslnie jest wylaczone
     * Jezeli jest wlaczone, to szukamy statycznej funkcji przesuwajacej mapke
     * Domyslnie, mozemy przesuwac tylko jedna mapke - to ostatnia ze strony
     */
    this.enableCitymap =  true ;

    /**
     * akcja http - wyszukiwanie elementow
     *  FIXME
     */

    this.searchAction = url + "ajaxproxy.php?step=9&hash=" + hash + '&' + extra_params;


    /**
     * Po ilu znakach mamy rozpoczac wyszukiwania
     */
    this.minChars = 0;

    /**
     * Maksymalna liczba elementow na liscie
     */
    this.maxElementsOnList = 9;


    /**
     * Wskaznik, na liste (element) w tym elemencie beda sie zawierac kolejne elementy
     */
    this.listRootElement = null;

    /**
     * Elementy na liscie
     */
    this.elements = new Array();
    /**
     * Wszystkie elementy
     */
    this.allElements = new Array();

    /**
     * Aktualnie podswietlany element listy
     */
    this.currentList = 0;
    /**
     * Aktualnie podswietlany element listy
     */
    this.startList = 0;

    /**
     * To czego szukalismy wczesniej
     */
    this.oldSearchRequest = '';

    /**
     * Czy rozpoczelismy juz wczytywanie danych
     */
    this.loadingStarted = false;
    /**
     * Czy wczytalismy juz dane
     */
    this.loadingDone = false;

    this.asp=false;

    /**
     * Funkcja aktywowana po kliknieciu gdziekolwiek na dokumencie
     * zapamietamy ta funkcja w momencie rysowania listy a skasujemy w momencie usuniecia narysowanej listy
     */
    this.documentBodyOnClick = null;

    /**
     * czy ruch myszka jest aktywny
     */
    this.mouseMoveActive = true;


    /**
     * Wskaznik na siebie
     */
    oThis = this;

    /**
     * keyup
     */
    iInputElement.onkeyup = function() {
        var oEvent = arguments[0] || window.event;
        oThis.keyUp( oEvent );
    }
    /**
     * keydown
     */
    iInputElement.onkeydown = function() {
        var oEvent = arguments[0] || window.event;
        oThis.keyDown( oEvent );
    }

    /**
     * aktualnie wybrany element
     */
    this.activeElement = null;

    /**
     * Dodatkowa akcja, ktora bedzie wykonana gdy zaladujemy juz dane
     */
    var oThis = this;
    this.onload = function() {
        oThis.filter();
        oThis.repaint();
    }

    oThis.load();
}

/**
 * gdy user podniesie klawisz to wyszukujemy
 */
DestinationAutoComplete.prototype.keyUp = function( oEvent ) {
    a = oEvent.keyCode;
    switch ( oEvent.keyCode ) {
        case 38:
        case 40:
        case 13:
        case 9:
            return false;
    }

    // gdy nic nie ma do szukania
    if ( this.inputElement.value.length < this.minChars ) {
        clearTimeout( this.searchTimeout ) ;
        this.dropList();
        return;
    }
    // gdy juz szukalismy tego
    if ( this.inputElement.value == this.oldSearchRequest ) {
        clearTimeout( this.searchTimeout ) ;
        return;
    }
    // ladowanie danych, jezeli nie zostalu juz zaladowane
    this.load();

    if ( this.loadingDone ) {
        this.filter();
        this.repaint();
    }
}
/**
 * Sprawdza nazwelementu wpisanego do inputa i jezeli jest taka to ustawia element w destination
 */
DestinationAutoComplete.prototype.check = function() {
    // wartosc w input
    var input=this.inputElement.value;
    // wszystkie elementy
    var all=this.allElements;
    // tablica pozycje wyszukiwanego tekstu w danym elemencie
    var tab=new Array(all.length);

    //przypisanie danych do tablicy
    for(var i=0;i<all.length;i++){
        tab[i]=all[i].name.toUpperCase().indexOf(input.toUpperCase());
    }
    // wyszukanie indexu elementu o najnizszej pozycji
    var t=0;
    for(var i=0;i<tab.length;i++){
        if(tab[t]==-1){
            t=i;
        }
    }
    for(var i=0;i<tab.length;i++){
        if((tab[i]<tab[t]) && (tab[i]>-1)) {
            t=i;
        }
    }

    // ustawienie destination
    if(tab[t]>-1){
        setDestination(all[t]);
    }
    return 1;
}

/**
 * Ladowanie danych, jezeli nie zostalu juz wczesniej zaladowane
 */
DestinationAutoComplete.prototype.load = function( oEvent ) {
    var oThis = this;
    if ( ! ( this.loadingStarted || this.loadingDone ) ) {
        this.loadingStarted = true;
        this.loadingDone    = false;
        cdAJAX.setDefaultParameters({
            group: null,
            unique: true
        });

        showAutoCompleteProgress();

        cdAJAX.get({
            url: oThis.searchAction,
            parameters : {
                "search" : oThis.inputElement.value
            },
            onSuccess : function(obj) {
                hideAutoCompleteProgress();
                var destinations = getDestinationsResponse();
                oThis.loadList( destinations );
                oThis.loadingDone = true;
                getDestinationsResponse = null;
                if ( oThis.onload ) {
                    //oThis.onload();
                }

                while(this.asp == true) {
                }

                if (params_present) $('#BVAction_start_search').click();
            },
            onError : function(obj) {
                oThis.raiseError( "Error while fetching destinations: " + obj.status );
            }
        });
    }
}

/**
 * Gdy nacisniemy klawisz to
 */
DestinationAutoComplete.prototype.keyDown = function(oEvent) {
    a = oEvent.keyCode;
    switch ( oEvent.keyCode ) {
        case 38:
            // do gory
            this.currentList--;
            if ( this.currentList < 0 ) this.currentList = 0;
            this.stopMouseMove();
            this.repaint();
            break;
        case 40:
            // do dolu
            this.currentList++;
            if ( this.currentList >= this.elements.length ) this.currentList = this.elements.length - 1;
            this.stopMouseMove();
            this.repaint();
            break;
        case 13:
            // enter
            if ( this.elements.length > 0 ) {
                this.select( this.elements[ this.currentList ] );
            }else{
                this.inputElement.value = '';
                destination = '';
            }
            break;
        case 9:
            // TAB
            if ( this.elements.length > 0 ) {
                this.select( this.elements[ this.currentList ] );
            } else {
                this.dropList();
                this.inputElement.value = '';
                destination = '';
            }
            break;
        default:
            //

            this.activeElement = null;
            break;
    }
    return false;
}

/**
 * Ukrywanie listy elementow
 */
DestinationAutoComplete.prototype.dropList = function() {
    this.showSelect();
    if ( this.listRootElement ) {
        document.body.removeChild( this.listRootElement );
        this.listRootElement = null;
    }
    this.elements = new Array();
    this.currentList = 0;
    this.startList = 0;
    this.oldSearchRequest = '';
    document.body.onclick = this.documentBodyOnClick;
    this.documentBodyOnClick = null;
}

/**
 * Utworzenie elementu nadrzednego dla listy
 */
DestinationAutoComplete.prototype.createRootListElement = function() {
    this.listRootElement = document.createElement('div');
    var p = this.getAbsolutePos( this.inputElement );
    this.listRootElement.className      = 'autocomplete';
    this.listRootElement.style.position = 'absolute';
    this.listRootElement.style.top      = ( p[3] ) + 'px';
    this.listRootElement.style.left     = ( p[0] ) + 'px';          // TODO, pozycja z jakiegos konfiga
    this.listRootElement.style.width    = ( p[2] - p[0] + 10 ) + 'px';
    document.body.appendChild( this.listRootElement );
}

/**
 * Element na liscie do utworzenia
 */
DestinationAutoComplete.prototype.createListElement = function(element, display, id) {
    this.elements.push( element );
    var div             = document.createElement('div');
    div.className       = 'element';
    var inptElem = this.inputElement.value;
    while(inptElem.search('[*]')>=0){
        inptElem = inptElem.replace('*', 'Z');
    }

    var underLine       = element.name.replace( new RegExp( '(' + inptElem + ')', 'i'  ), '<u>$1</u>' );
    div.innerHTML       = '<span classname="'+element.type+'">' + underLine + '</span>';
    div.style.display   = display ? 'block' : 'none';
    div.id              = this.idPrefix + this.inputElement.id + id;
    var oThis           = this;
    div.onmouseover     = function() { me = arguments[0] || window.event; return oThis.mouseOver( me ); };
    div.onmouseout      = function() { me = arguments[0] || window.event; return oThis.mouseOut( me ); };
    div.onclick         = function() { me = arguments[0] || window.event; return oThis.click( me ); };
    this.listRootElement.appendChild( div );
}

DestinationAutoComplete.prototype.raiseError = function(message) {
    alert(message);
}


/**
 * Wczytanie danych
 */
DestinationAutoComplete.prototype.loadList = function(destinations) {
    this.allElements = destinations;
}

/**
 * Filtrowanie i sortowanie danych
 */
DestinationAutoComplete.prototype.filter = function() {
    this.dropList();
    this.createRootListElement();
    var j = 0;
    var inptElem = this.inputElement.value;
    while(inptElem.search('[*]')>=0){
        inptElem = inptElem.replace('*', 'Z');
    }

    var re = new RegExp( inptElem, 'i' );
    var toSort = new Array();
    // filtrowanie
    for ( var i = 0; i < this.allElements.length; i++ ) {
        var e = this.allElements[i];
        // sprawdzenie, czy tekst pasuje
        if ( ! re.test( e.name ) ) continue;
        toSort.push( e );
    }
    // sortowanie, jezeli pasuje z przodu to lepiej
    var reSort = new RegExp( '^' + inptElem, 'i' );
    toSort.sort( function( a, b ) {
        var ac = reSort.test( a.name );
        var bc = reSort.test( b.name );
        if ( ac == bc ) return 0;
        if ( ac ) return -1;
        if ( bc ) return  1;
        return 0;
    } );
    // dopisywanie
    for ( var i = 0; i < toSort.length; i++ ) {
        var e = toSort[i];
        // dopisanie elementu do listy elementow wyswietlanych
        this.createListElement( e, j < this.maxElementsOnList, j );
        j++;
    }
    if ( 0 == j ) {
        this.dropList();
    }
}
/**
 * Odswiezenie elementow na liscie
 */
DestinationAutoComplete.prototype.repaint = function() {
    this.activeElement = null;
    if ( ! this.listRootElement ) return;
    var divs = this.listRootElement.getElementsByTagName('div');
    var j = 0;
    if( this.currentList >= this.startList + this.maxElementsOnList ) {
        this.startList = this.currentList - this.maxElementsOnList + 1;
    } else if ( this.currentList < this.startList ) {
        this.startList = this.currentList;
    }
    for ( var i in divs ) {
        if ( 'object' != typeof divs[i] ) continue;
        divs[i].style.display = j >= this.startList && j < this.startList + this.maxElementsOnList ? 'block' : 'none';
        divs[j].className = j == this.currentList ? 'element over' : 'element';
        j++;
    }
    // ukrycie selektow pod spodem listy, poprawka dla IE
    this.hideSelect();
    // wylaczenie listy gdy ktos kliknie gdziekolwiek myszka
    if (!this.documentBodyOnClick ) {
        this.documentBodyOnClick = document.body.onclick;
        destination = '';
    }
    var oThis = this;
    var tmpFn = function() {
        document.body.onclick = function() {
            oThis.dropList();
        }
    }
    setTimeout( tmpFn, 50 );
}

/**
 * gdy myszka jest nad elementem
 */
DestinationAutoComplete.prototype.mouseOver = function() {
    if ( ! this.mouseMoveActive ) return;
    var mouseEvent = arguments[0] || window.event;
    this.currentList = this.getTargetIdForMouseEvent( mouseEvent );
    this.repaint();
}
/**
 * gdy myszka oposcila element
 */
DestinationAutoComplete.prototype.mouseOut = function() {
}
/**
 * po kliknieciu przyciskiem myszki na element
 */
DestinationAutoComplete.prototype.click = function() {
    var mouseEvent = arguments[0] || window.event;
    var currentList = this.getTargetIdForMouseEvent( mouseEvent );
    this.select( this.elements[ currentList ] );
}
/**
 * po wybranie czegos ma sie uruchomi ta funkcja
 */
DestinationAutoComplete.prototype.select = function( element ) {
    this.inputElement.value = element.name;
    this.activeElement = element;
    setDestination(element);
    if(this.enableCitymap){
        this.citymapMoveTo(element.lat,element.lng,element.zoom);
    }
    this.dropList();
}

/**
 * Czasowe zatrzymanie poruszanie aktywnosci myszki
 */
DestinationAutoComplete.prototype.stopMouseMove = function() {
    this.mouseMoveActive = false;
    var oThis = this;
    var tmpFn = function() {
        oThis.mouseMoveActive = true;
    }
    setTimeout( tmpFn, 100 );
}


/**
 * Znalezienie elementu listy powiazanego z zdarzeniem myszki
 */
DestinationAutoComplete.prototype.getTargetIdForMouseEvent = function( mouseEvent ) {
    var target;
    if (mouseEvent.target) {
        target = mouseEvent.target;
    } else if (mouseEvent.srcElement) {
        target = mouseEvent.srcElement;
    }
    if ( ! target ) return;

    if (target.nodeType == 3) {
        // defeat Safari bug
        target = target.parentNode;
    }
    while( 'DIV' != target.tagName.toUpperCase() ) {
        target = target.parentNode;
    }
    var re = new RegExp( this.idPrefix + this.inputElement.id + "([0-9]+)" );
    var ma = re.exec( target.id );
    return ma[1];

}

/**
 * Pozycja elementu absolutna na stronie
 */
DestinationAutoComplete.prototype.getAbsolutePos = function(oElem) {
    var oTemp = typeof oElem == 'string' ? document.getElementById( oElem ) : oElem;
    oElem = oTemp;
    var absLeft = 0, absTop = 0;
    while ( oTemp ) {
        absTop += oTemp.offsetTop;
        absLeft += oTemp.offsetLeft;
        oTemp = oTemp.offsetParent;
    }
    return new Array(absLeft, absTop, absLeft + oElem.offsetWidth, absTop + oElem.offsetHeight );
}

/**
 * Pobranie aktualnej wartosci
 *  sprawdzamy, czy aktualna wartosc jest zapisane w zmiennej prywatnej.
 *  jezeli tak to jupi
 *  jezeli nie to probujemy znalezc wartosc, ktorej nazwa jest rowna szukanemu tekstowi
 *  jezeli sie udalo, to zwracamy pierwsza znaleziona wartosc
 *  jezeli sie nie udalo to zwracamy null
 */
DestinationAutoComplete.prototype.get = function() {
    if ( this.activeElement ) return this.activeElement;
    var v = this.inputElement.value.toUpperCase();
    for ( var i = 0; i < this.allElements.length; i++ ) {
        var e = this.allElements[i];
        if ( v == e.name.toUpperCase() ) {
            this.activeElement = e;
            return e;
        }
    }
    return null;
}

/**
 * Ukrycie selektow pod spodem listy
 */
DestinationAutoComplete.prototype.hideSelect = function() {
    this.showSelect();
    this._selects = new Array();
    if (!this.listRootElement) return;
    var pm = this.getAbsolutePos(this.listRootElement);
    var selects = document.getElementsByTagName('select');
    for (var i in selects) {
        var el = selects[i];
        if (this._inSelects(el)) continue;
        if ('object' != typeof el) continue;
        var ps = this.getAbsolutePos(el);
        if ((pm[2] < ps[0] || pm[3] < ps[1]) || (pm[0] > ps[2] || pm[1] > ps[3])) continue;
        var lastVisibility = el.style.visibility;
        el.style.visibility='hidden';
        this._selects.push(new Array(el, lastVisibility));
    }
}

/**
 * Pokazanie ukrytych selektow
 */
DestinationAutoComplete.prototype.showSelect = function() {
    if (!this._selects) return;
    var i;
    while (i = this._selects.pop()) {
        i[0].style.visibility = i[1];
    }
}


/**
 * Sprawdzamy, czy element jest juz na liscie ukrytych selektow
 */
DestinationAutoComplete.prototype._inSelects = function( iTest ) {
    var i;
    while (i in this._selects) {
        if (this._selects[i][0] == iTest) return true;
    }
    return false;
}

/**
 * Pobranie elementu z listy wszystkich elementow,
 * Funkcja moze byc uzyteczna do sprawdzenie, czy element jest na liscie
 * Funkcja zaklada, ze elementy zostaly juz zaladowane
 */
DestinationAutoComplete.prototype._getFromAllElements = function(type, id) {
    for (var i = 0; i < this.allElements.length; i++) {
        var el = this.allElements[i]
        if (el.type != type) continue;
        if (el.id != id) continue;
        return el;
    }
    return null;
}

/**
 * Ustawienie wybranego elementu na liscie wyszukiwania,
 * pod warunkiem ze dane zostalu juz zaladowane
 */
DestinationAutoComplete.prototype._set = function(type, id) {
    var el = this._getFromAllElements(type, id);
    if (!el) return;
    this.activeElement = el;
    this.inputElement.value = el.name;
}

/**
 * Ustawienie wybranego elementu na liscie
 * Jezeli dane nie zostaly jeszcze zaladowane to je ladujemy
 */
DestinationAutoComplete.prototype.set = function(type, id) {
    if (this.loadingDone) {
        this._set(type, id);
        return;
    }
    var oThis = this;
    this.onload = function() {
        oThis._set(type, id);
    }
    this.load();
}
/**
 * Przesuwanie mapka,
 * Jezeli na stronie jest mapka - obiekt Citymap
 * To probuje wywolac statyczna funkcje przesuwajaca ten obiekt
 */
DestinationAutoComplete.prototype.citymapMoveTo = function(lat, lng, zoom) {
    if("undefined" == typeof CityMap){
        return;
    }
    CityMap.moveCurrentMapTo(lat, lng, zoom);
}

//------------------------------------------------------------------------------
// KALENDARZ - WYBIERANIE DAT
//------------------------------------------------------------------------------

/**
 *  Wybieranie daty d-Ym zintegrowane z kalendarzykiem jscalendar
 *
 *  Funkcje publiczne posluguja sie data w formacie 'Y-m-d'
 *  Funkcje prywatne uzywaja daty w obiekcie Date js
 */

/**
 * Utworzenie obiektu
 */
function DateSelect(iId) {
    /**
     * identyfikator, wszystkie elementy powinny miec odpowiednie _id
     */
    this._id = iId;
    /**
     * ja byc ja
     */
    var oThis = this;
    /**
     * Inicjacja obiektu kalendarzyka
     */

    Calendar.setup({
        daFormat       : "%Y-%m-%d",
        displayArea    : oThis._id + "_value",
        button         : oThis._id + "_button",
        range          : new Array( this._getFirstDate().getFullYear(), this._getLastDate().getFullYear() ),
        onUpdate       : function( cal ) { oThis._updateCalendar( cal ); },
        dateStatusFunc : function( date ) { return oThis._getDateStatus( date ); },
        showsTime      : false,
        singleClick    : true
    });
    /**
     * Ustalenie zakresow z selektow
     */
    this.setRange( this.formatDate( this._getFirstDate() ), this.formatDate( this._getLastDate() ) );
    this.set( this.formatDate( this._getFirstDate() ) );
    /**
     * funkcja, ktora ma zostac uruchomina w momencie gdy elementy selektora sie zmieniaja
     */
    document.getElementById( this._id + '_Ym' ).onchange = function() { oThis._updateSelect(); };
    document.getElementById( this._id + '_d' ).onchange = function() { oThis._updateSelect(); };
}


/**
 * Ustawienie aktualnej daty
 */
DateSelect.prototype.set = function( dateString ) {
    var date = typeof dateString == 'string' ? this.parseDate( dateString ) : dateString;
    if ( date >= this._getFirstDate() && date <= this._getLastDate() ) {
        this._setCalendar( date );
        this._setSelect( date );
    }
}
/**
 * Pobranie aktualnej daty z obiektu
 */
DateSelect.prototype.get = function() {
    return this.formatDate( this.parseDate( document.getElementById( this._id + '_value' ).innerHTML ) );
}
/**
 * Zwraca date dla pierwszego dnia w przedziale w selektach
 */
DateSelect.prototype._getFirstDate = function() {
    var Yms = document.getElementById( this._id + '_Ym' );
    var Ymd = Yms.options[0].value + '-01';
    return this.parseDate( Ymd );
}
/**
 * Zwraca date dla ostatniego dnia w przedziale w selektach
 */
DateSelect.prototype._getLastDate = function() {
    var Yms = document.getElementById( this._id + '_Ym' );
    var Ymd = Yms.options[ Yms.options.length - 1 ].value + '-01';
    var d = this.parseDate( Ymd );
    d.setDate( d.getMonthDays() );
    return d;
}

/**
 * Funkcja uruchamiana po wybraniu daty
 */
DateSelect.prototype._updateCalendar = function( cal ) {
    this._setCalendar( cal.date );
    this._setSelect( cal.date );
    if(this._id == 'checkindate'){
        this._calendarSetCheckinRange();
    }
    else{
        this._calendarSetCheckoutRange();
    }
    this._onchange();
}
/**
 * Funkcja odpalana gdy elementy selecta sie zmienia
 */
DateSelect.prototype._updateSelect = function() {

    var dateString = this._getSelectedValue( document.getElementById( this._id + '_Ym' ) );
    var d1 = this.parseDate( dateString + '-' + this._getSelectedValue( document.getElementById( this._id + '_d' ) ) );
    var d2 = this.parseDate( dateString + '-01' );
    if ( d1.getMonth() != d2.getMonth() ) {
        // mamy 30 lutego, 31 kwietnia lub itp
        d1 = d2;
        d1.setDate( d1.getMonthDays() );
    }
    if ( d1 < this._rangeStartDate ) {
        d1 = this._rangeStartDate;
    } else if ( d1 > this._rangeEndDate ) {
        d1 = this._rangeEndDate;
    }

    this._setSelect( d1 );
    this._setCalendar( d1 );
    if(this._id == 'checkindate'){
        this._calendarSetCheckinRange();
    }
    else{
        this._calendarSetCheckoutRange();
    }
    this._onchange();
}

    // gdy manipulujemy datami , dbamy o zle terminy
DateSelect.prototype._calendarSetCheckinRange = function() {
        // checkin i checkout - obiekty trworzone w template/formular.html
        // funkcja Date.parseDate jest stworzona w kalendarzyku jscalendar
        var d = Date.parseDate( checkin.get(), "%Y-%m-%d" );
        var d1 = Date.parseDate( checkout.get(), "%Y-%m-%d" );
        var dateDiff = parseInt((d1.getTime()-d.getTime())/86400000);
        d.setDate( d.getDate() + parseInt(servicetime) );

        if (dateDiff <= 0) checkout.set(d.print("%Y-%m-%d"));
    }
DateSelect.prototype._calendarSetCheckoutRange = function() {
        // checkin i checkout - obiekty trworzone w template/formular.html
        // funkcja Date.parseDate jest stworzona w kalendarzyku jscalendar
        var d = Date.parseDate( checkin.get(), "%Y-%m-%d" );
        var d1 = Date.parseDate( checkout.get(), "%Y-%m-%d" );
        var dateDiff = parseInt((d1.getTime()-d.getTime())/86400000);
        if (dateDiff <= 0) {
            d.setDate(d.getDate() + parseInt(servicetime));
            checkout.set(d.print("%Y-%m-%d"));
        }
    }


/**
 * Ustawienie daty dla selektow
 */
DateSelect.prototype._setSelect = function( date ) {
    var Ym = date.getFullYear() + '-' + this._formatDatePart( date.getMonth()+1 );
    var d  = '' + date.getDate();
    var oThis = this;
    this._setSelectByValue( document.getElementById( oThis._id + '_Ym' ), Ym );
    this._setSelectByValue( document.getElementById( oThis._id + '_d' ), d );
}
/**
 * Ustawienie daty dla selektow
 */
DateSelect.prototype._setCalendar = function( date ) {
    document.getElementById( this._id + '_value' ).innerHTML = this.formatDate( date );
}

/**
 * Pobiera string w formacie yyyy-mm-dd i zwraca obiekt Date
 */
DateSelect.prototype.parseDate = function( dateString ) {

    var str = new String(dateString);
    var array = str.split('-');
    if (array.length!=3) {
        return null;
    }
    var year = array[0];
    var month = array[1].charAt(0)=='0' ? parseInt(array[1].substr(1, 1)) : parseInt(array[1]);
    var day = array[2].charAt(0)=='0' ? parseInt(array[2].substr(1, 1)) : parseInt(array[2]);
    var date = new Date(year, month-1, day);
    if (isNaN(date)) {
        return null;
    }
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    return date;
}

/**
 * Zamienia obiekt Date na string w formacie YYYY-MM-DD.
 */
DateSelect.prototype.formatDate = function( date ) {
    return date.getFullYear() + "-" + this._formatDatePart(date.getMonth()+1) +
        "-" + this._formatDatePart(date.getDate());
}
/**
 * Uzupelnia element daty o 0 z przodu
 */
DateSelect.prototype._formatDatePart = function( value ) {
    var v = new String(value);
    return v.length==1 ? "0"+v : v;
}

/**
 * Ustawienie elementu typu select na dana wartosc
 */
DateSelect.prototype._setSelectByValue = function(selectElement , value) {
    // czy to cos ma opcjie
    if( !selectElement.options ) {
        return;
    }
    for( var i=0; i<selectElement.options.length; i++ ) {
        if( selectElement.options[i].value != value ) {
            continue;
        }
        selectElement.selectedIndex = i;
        return;
    }
}

/**
 * Zwraca wybrana wartosc dla selecta
 */
DateSelect.prototype._getSelectedValue = function(selectElement) {
    if ( ! selectElement ) return;
    return selectElement.options[ selectElement.selectedIndex ].value;
}

/**
 * Pobiera status dla danej daty.
 *  Zwraca true, gdy element ma nie byc pokazywany.
 *  w przeciwynym wypadku zwraca false
 */
DateSelect.prototype._getDateStatus = function(date) {
    if ( date < this._rangeStartDate || date > this._rangeEndDate ) {
        return true;
    }
    return false;
    // return this._rangeStartDate > date || this._rangeEndDate < date;
}
/**
 * Pobierania nazwy dla miesiaca
 */
DateSelect.prototype._getMonthString = function(month) {
    return 'aaa' + month;
}
/**
 * Ustalenie zakresow
 */
DateSelect.prototype.setRange = function( iRangeStartDateString, iRangeEndDateString ) {
    var rs = iRangeStartDateString ? this.parseDate( iRangeStartDateString ) : this._rangeStartDate;
    var re = iRangeEndDateString   ? this.parseDate( iRangeEndDateString )   : this._rangeEndDate;
    if ( rs >= this._getFirstDate() ) {
        this._rangeStartDate = rs;
    } else {
        this._rangeStartDate = this._getFirstDate();
    }
    if (re <= this._getLastDate() ) {
        this._rangeEndDate   = re;
    } else {
        this._rangeEndDate   = this._getLastDate();
    }
}

/**
 * Ustalenie poczatku zakresu
 */
DateSelect.prototype.setStartOfRange = function(iRangeStartDateString) {
    var rs = iRangeStartDateString ? this.parseDate( iRangeStartDateString ) : this._rangeStartDate;
    if ( rs >= this._getFirstDate() ) {
        this._rangeStartDate = rs;
    } else {
        this._rangeStartDate = this._getFirstDate();
    }
}

/**
 * Funkcja odpalana po zmianie daty obojetnie czy z kalendarza, czy z selektow.
 * Jezeli mamy jakis callback to go uruchamiamy
 */
DateSelect.prototype._onchange = function() {
    if ( this._onchangeCallback ) {
        this._onchangeCallback( this );
    }
}
/**
 * ustawienie funkcji zwrotne uruchamianej podczas modyfikacji
 */
DateSelect.prototype.setOnchangeCallback = function(iCallback) {
    this._onchangeCallback = iCallback;
}


function url_decode(psEncodeString)
{
    var lsRegExp = /\+/g;
    var ie_ver = getInternetExplorerVersion();
    if (ie_ver != -1) return psEncodeString;
    psEncodeString = psEncodeString.replace(/%25/g, '%');
    return utf8_decode(unescape(String(psEncodeString).replace(lsRegExp, " ")));
}


function utf8_decode(utftext)
{
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;
    
    while (i < utftext.length) {
        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        } else if((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i + 1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = utftext.charCodeAt(i + 1);
            c3 = utftext.charCodeAt(i + 2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return string;
}
