<commit_before>// city object
var city = null;

// text
TEXT = {
    zero: '0',
    empty: '',
    RU: {
        backToDefaultPlace: 'Вы вернулись в исходное положение',
        editingFinished: 'Редактирования завершено',
        modePointEditor: 'Режим редактирования остановок',
        modeRouteEditor: 'Режим редактирования маршрутов',
        thisActionIsNotAllowed: 'Данное действие не доступно в режиме редактора',
        noDataToSave: 'Нет данных для сохранения',
        nothingSelected: 'Ничего не выбрано',
        selectFirstEndPointOnMap: 'Выберите начальную и конечную точку на карте',
        pointRemoved: 'Метка удалена',
        pointSaved: 'Метка сохранена',
        routeSaved: 'Маршрут сохранен',
        routeEndNotSelected: 'Конец маршрута не задан',
        routeStartNotSelected: 'Начало маршрута не задано',
        notSelected: 'Не выбрано',
        noData: 'Нет данных',
        noAvialableRoutes: 'Нет доступных маршрутов',
        nameNotChoosed: 'Имя не задано',
        notSet: 'Не задано',
        sessionEnd: 'Текущая сессия завершена',
        authSucc: 'Вы успешно авторизированы',
        login: 'Вход',
        exit: 'Выход',
        minute: 'мин.',
        transArrived: 'прибыл'
    },
    ENG: {
        backToDefaultPlace: 'You have back to default place',
        editingFinished: 'Editing finished',
        modePointEditor: 'Point editor mode',
        modeRouteEditor: 'Route editor mode',
        noDataToSave: 'No data to save',
        nothingSelected: 'Nothing selected',
        selectFirstEndPointOnMap: 'Select first and end point on map',
        pointRemoved: 'Point removed successfully',
        pointSaved: 'Point saved successfully',
        routeSaved: 'Route saved successfully',
        routeEndNotSelected: 'Route end not selected',
        routeStartNotSelected: 'Route start not selected',
        noData: 'No data',
        noAvialableRoutes: 'No avialable routes',
        nameNotChoosed: 'Name not choosed',
        notSelected: 'Not selected',
        notSet: 'Not set',
        sessionEnd: 'Current session finished',
        authSucc: 'You have been authorized successfully',
        login: 'Login',
        exit: 'Exit',
        minute: 'min.',
        transArrived: 'arrived'
    }
};

// $.ready handler
$(document).ready(function() {
    // links to page objects
    var objects = {
        body : $('body'),
        alertbox: $('#alertbox'),
        map: document.getElementById('map_canvas'),
        onAuth : $('#auth'),
        control: $('#control'),
        editPoints: $('#edit_points'),
        editRoutes: $('#edit_routes'),
        editGuide: $('#edit_guide'),
        pointEditor: {
            open: $('#open-point-editor'),
            close: $('#point-editor-close'),
            save: $('#point-save'),
            remove: $('#point-delete'),
            valueLat: $('#label_posx'),
            valueLng: $('#label_posy'),
            valueTitle: $('#label_name')
        },
        routeEditor: {
            open: $('#open-route-editor'),
            close: $('#route-editor-close'),
            save: $('#route-save'),
            remove: $('#route-route-remove'),
            start: $('#button-route-start'),
            end: $('#button-route-end'),
            valueTitle: $('#route-name'),
            valueStart: $('#route-start'),
            valueEnd: $('#route-end')
        },
        guideEditor : {
            open: $('#open-guide'),
            close: $('#guide-close'),
            save: $('#guide-save'),
            create: $('#guide-new'),
            valueStart: $('#guide_start'),
            valueEnd: $('#guide_end'),
            valueLength: $('#guide_length'),
            valueUrl: $('#guide_url'),
            valueIfPlacesShowed: $('#guide-show-places')
        },
        toolBox: {
            base: $('#toolbox'),
            data: $('#toolbox-data'),
            activeGuide: $('#tab-guide-active'),
            activePoint: $('#tab-point-active'),
            activeRoute: $('#tab-route-active')
        },
        loginBox: {
            base: $('#authform'),
            login: $('#auth-login'),
            pass: $('#auth-pass'),
            act: $('#auth-submit')
        },
        searchBar: {
            base: $('#main-search'),
            chosen: $('.chosen'),
            option: function() {
                return $('option');
            },
            groups: $('optgroup'),
            main: function() {
                return $('#main_search_chzn');
            },
            drop: function() {
                return $('.chzn-drop');
            }
        }
    };

    // livecity settings
    var settings = {
        zoom: 15,
        center: new google.maps.LatLng(51.4982000,31.2893500),
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle,
            position: google.maps.ControlPosition.BOTTOM_LEFT
        },
        navigationControl: true,
        navigationControlOptions: {
            style: google.maps.NavigationControlStyle.SMALL
        },
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        lang: 'RU'
    };
    // create new city
    city = new Livecity(objects,settings);
    // init city
    city.init();
    // set update function with interval
    // TBD
    setInterval('city.update()',2000);
    // Edit stations click handler
    objects.pointEditor.open.click(function() { city.onEditPoint(); });
    // edit route handler
    objects.routeEditor.open.click(function () { city.onEditRoute();});
    // guide handler
    objects.guideEditor.open.click(function() {city.onEditGuide();});
    // Close edit panel handler
    objects.pointEditor.save.click(function () {city.onSavePoint();});
    // Cancel edit point click handler
    objects.pointEditor.close.click(function () {city.onClosePointEditor();});
    // Cancel edit route click handler
    objects.routeEditor.close.click(function () {city.onCloseRouteEditor();});
    // Cancel guide
    objects.guideEditor.close.click(function() {city.onCloseGuideEditor();});
    // remove button click
    objects.pointEditor.remove.click(function () {city.onDeletePoint();});
    // back to city center
    objects.control.click(function (){city.setCenter();});
    // save route handler
    objects.routeEditor.save.click(function() { city.routeBuilder.save();});
    // set route start handler
    objects.routeEditor.start.click(function() {city.routeBuilder.setStart();});
    // set route start handler
    objects.routeEditor.end.click(function() {city.routeBuilder.setEnd();});
    // onAuth button handler
    objects.onAuth.click(function() {city.onAuth();});
    // login button handler
    objects.loginBox.base.on('submit', function(e) {city.onLogin(e)});
    // guide checkbox
    objects.guideEditor.valueIfPlacesShowed.change(function() {
        // check 'checked' property
        if (objects.guideEditor.valueIfPlacesShowed.prop('checked')) city.pointLayer.setVisible(true);
        else city.pointLayer.setVisible(false);
    });
    // new guide handler
    objects.guideEditor.create.click(function() {city.toolBox.__guideEditor.popAll();});
    // search bar init
    objects.searchBar.chosen.chosen({
            no_results_text: TEXT[city.getLang()],
            width: '100%'
    }).change(function() {
            city.searchBar.init($(this).val());
    });
    // fixing searchBar width... [TEMPORARY]
    objects.searchBar.main().css('width', '100%');
    objects.searchBar.drop().css('width', '100%');
    // key down handler
    objects.body.on('keydown',function(e) {
        // escape handler
        if (e.keyCode === 27) city.onEscape();
    });

    /*
     * TEXT SET
     */

    $.get('/app/version', function(version) {
        objects.control.html('livecity<div class="small"><sup> ' + version + '</sup></div> ');
    });
});

/*
 * City Class
 * @objects - link to HTML objects
 * @settings - settings for livecity
 */
function Livecity(objects,settings) {

    /*
     * PUBLIC ATTRIBUTES
     */

    // static - static functions and values
    this.static = {
        ICON_BLUE: function() {
            return new google.maps.MarkerImage('img/stop2.png', new google.maps.Size(16, 16), new google.maps.Point(0, 0), new google.maps.Point(8, 10));
        },
        ICON_RED: function() {
            return new google.maps.MarkerImage('img/stop-m2.png', new google.maps.Size(16, 16), new google.maps.Point(0, 0), new google.maps.Point(8, 10));
        },
        ICON_TRANS: function() {
            return new google.maps.MarkerImage('img/bus.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 33));
        },
        ICON_A: function() {
            return new google.maps.MarkerImage('http://www.google.com/mapfiles/markerA.png', new google.maps.Size(36, 36), new google.maps.Point(0, 0), new google.maps.Point(9, 33));
        },
        ICON_B: function() {
            return new google.maps.MarkerImage('http://www.google.com/mapfiles/markerB.png', new google.maps.Size(36, 36), new google.maps.Point(0, 0), new google.maps.Point(9, 33));
        },
        TYPE_POST: 'POST',
        TYPE_JSON: 'JSON',
        TYPE_GET: 'GET',
        TYPE_DELETE: 'DELETE',
        TYPE_PUT: 'PUT'
    };

    /*
     *  PRIVATE ATTRIBUTES
     */

    // UID
    var __uid = null;
    // objects
    var __objects = objects;
    // set settings
    var __settings = settings;
    // map
    var __map = new google.maps.Map(__objects.map,__settings);

    /*
     * PUBLIC GETTERS & SETTERS
     */

    // GET uid
    this.getUID = function() {
        return __uid;
    };
    // SET uid
    this.setUID = function(uid) {
        __uid = uid;
    };
    // GET objects
    this.getObjects = function() {
        return __objects;
    };
    // SET objects
    this.setObjects = function(objs) {
        __objects = objs;
    };
    // GET selected object
    this.getObject = function(name) {
        return __objects[name];
    };
    // SET selected object
    this.setObject = function(name,value) {
        __objects[name] = value;
    };
    // GET property
    this.getProperty = function(name) {
        return __settings[name];
    };
    // SET property
    this.setProperty = function(name,value) {
        __settings[name] = value;
    };
    // GET settings
    this.getProperties = function() {
        return __settings;
    };
    // GET lang property
    this.getLang = function() {
        return __settings.lang;
    };
    // SET lang property
    this.setLang = function(lng) {
        __settings.lang = lng;
    };
    // GET map
    this.getMap = function() {
        return __map;
    };
    // notifier
    this.notifier = new Notifier(this);
    // point layer
    this.pointLayer = new PointLayer(this);
    // route layer
    this.routeLayer = new RouteLayer(this);
    // trans layer
    this.transLayer = new TransLayer(this);
    // search bar
    this.searchBar = new SearchBar(this);
    // tool box
    this.toolBox = new ToolBox(this);
    // auth box
    this.loginBox = new LoginBox(this);
}

// [P] init - init map [DEPRECATED]
Livecity.prototype.init = function() {
    // link to main document
    var link = this;
    // load points on map
    this.pointLayer.load(function() {
        link.routeLayer.load(function(){
            link.searchBar.update();
        });
    });
    // map click handler
    google.maps.event.addListener(this.getMap(), 'click', function(event) {
        // point editor mode
        if (link.toolBox.isPointEditorOpened()) {
            var point = link.addPoint(event.latLng);
            point.save(function() {
                link.pointLayer.add(point);
                link.pointLayer.setCurrent(point);
                link.searchBar.update();
                link.outMsg(TEXT[link.getLang()].pointSaved,"green");
            });
        }
        // guide editor mode
        if (link.toolBox.isGuideEditorOpened()) {
            // temporary
            link.toolBox.__guideEditor.push(event.latLng);
        }
    });
    this.toolBox.maximize(false);
    this.loginBox.checkAuthorization(function(res) {
        link.login(res);
    });
    this.update();
};

// [P] outMsg - show notification message
Livecity.prototype.outMsg = function(text,color) {
    this.notifier.msg(text,color);
};

// [P] onEscape - Escape button handler
Livecity.prototype.onEscape = function() {
    // point editor mode
    if (this.toolBox.isPointEditorOpened()) {
        if (this.pointLayer.getCurrent()) {
            this.pointLayer.setCurrent();
            this.toolBox.clear();
        }
        else this.onClosePointEditor();
    }
    if (this.toolBox.isRouteEditorOpened()) {
        this.onCloseRouteEditor();
    }
    if (this.toolBox.isGuideEditorOpened()) {
        if (!this.toolBox.__guideEditor.empty()) {
            this.toolBox.__guideEditor.popAll();
            this.toolBox.clear();
        }
        else this.onCloseGuideEditor();
    }
};

// [P] setEditPointData - set edits for editing marker
Livecity.prototype.setEditPointData = function(position, title, focus) {
    var lat = position.lat();
    var lng = position.lng();
    // UPD - add option Round?
    this.getObjects().pointEditor.valueLat.text(Number(lat).toFixed(4));
    this.getObjects().pointEditor.valueLng.text(Number(lng).toFixed(4));
    this.getObjects().pointEditor.valueTitle.val(title);
    // UPD
    if (focus) this.getObjects().pointEditor.valueTitle.focus();
};

// [P] addPoint - add new point on map
Livecity.prototype.addPoint = function(position) {
    var title = "id" + (this.pointLayer.points.length);
    var point = new MapPoint(this, null, position, this.static.ICON_RED(), title);
    point.getMarker().setDraggable(true);
    point.setVisible(true);
    this.setEditPointData(position, title, true);
    return point;
};

// [P] setCenter - set map to selected map position
Livecity.prototype.setCenter = function(center) {
    // if center is not selected, set map center default value
    if (!center) {
        this.getMap().setCenter(this.getProperty('center'));
        this.outMsg(TEXT[this.getLang()].backToDefaultPlace,"green");
    }
    // if selected - set value and save to settings
    else {
        this.getMap().setCenter(center);
        this.setProperty('center',center);
    }
};

Livecity.prototype.login = function(is) {
    if (true === is) {
        this.toolBox.show(true);
        this.getObjects().onAuth.css("background", "url('img/lock.png') right no-repeat");
        this.getObjects().onAuth.text(TEXT[this.getLang()].exit);
        this.loginBox.setVisible(false);

    }
    else {
        this.toolBox.show(false);
        if (this.toolBox.isRouteEditorOpened()) this.onCloseRouteEditor();
        if (this.toolBox.isPointEditorOpened()) this.onClosePointEditor();
        if (this.toolBox.isGuideEditorOpened()) this.onCloseGuideEditor();
        this.getObjects().onAuth.css("background", "url('img/key.png') right no-repeat");
        this.getObjects().onAuth.text(TEXT[this.getLang()].login);
    }
};

// [P] onAuth - authorize user/end session
Livecity.prototype.onAuth = function(change) {
    var _this = this;
    this.loginBox.checkAuthorization(function(res) {
        if (true === res) {
            _this.loginBox.logout(function(res){
                if (true === res) {
                    _this.login(false);
                    _this.outMsg(TEXT[_this.getLang()].sessionEnd,"green");
                }
                else {
                    // TBD
                    // logout err
                }
            })
        }
        else {
            _this.loginBox.setVisible(true);
        }
    });
};

Livecity.prototype.onLogin = function(e) {
    var _this = this;
    this.loginBox.login(this.getObjects().loginBox.base, function(result){
        if (true === result) {
            _this.login(true);
            _this.outMsg(TEXT[_this.getLang()].authSucc,"green");
        };
    });
    e.preventDefault();
};

// [P] update - update trans layer on a map
Livecity.prototype.update = function() {
    this.transLayer.update();
};

// [P] onSavePoint - save point handler [DEPRECATED]
Livecity.prototype.onSavePoint = function() {
    var link = this;
    var current = this.pointLayer.getCurrent();
    if (!current) this.outMsg(TEXT[this.getLang()].noDataToSave,"red");
    else {
        current.save(function () {
            link.searchBar.update();
            link.outMsg(TEXT[link.getLang()].pointSaved,"green");
        });<commit_msg>notification on Login error<commit_after>// city object
var city = null;

// text
TEXT = {
    zero: '0',
    empty: '',
    RU: {
        backToDefaultPlace: 'Вы вернулись в исходное положение',
        editingFinished: 'Редактирования завершено',
        modePointEditor: 'Режим редактирования остановок',
        modeRouteEditor: 'Режим редактирования маршрутов',
        thisActionIsNotAllowed: 'Данное действие не доступно в режиме редактора',
        noDataToSave: 'Нет данных для сохранения',
        nothingSelected: 'Ничего не выбрано',
        selectFirstEndPointOnMap: 'Выберите начальную и конечную точку на карте',
        pointRemoved: 'Метка удалена',
        pointSaved: 'Метка сохранена',
        routeSaved: 'Маршрут сохранен',
        routeEndNotSelected: 'Конец маршрута не задан',
        routeStartNotSelected: 'Начало маршрута не задано',
        notSelected: 'Не выбрано',
        noData: 'Нет данных',
        noAvialableRoutes: 'Нет доступных маршрутов',
        nameNotChoosed: 'Имя не задано',
        notSet: 'Не задано',
        sessionEnd: 'Текущая сессия завершена',
        authSucc: 'Вы успешно авторизированы',
        authErr: 'Неверный логин и(или) пароль',
        login: 'Вход',
        exit: 'Выход',
        minute: 'мин.',
        transArrived: 'прибыл'
    },
    ENG: {
        backToDefaultPlace: 'You have back to default place',
        editingFinished: 'Editing finished',
        modePointEditor: 'Point editor mode',
        modeRouteEditor: 'Route editor mode',
        noDataToSave: 'No data to save',
        nothingSelected: 'Nothing selected',
        selectFirstEndPointOnMap: 'Select first and end point on map',
        pointRemoved: 'Point removed successfully',
        pointSaved: 'Point saved successfully',
        routeSaved: 'Route saved successfully',
        routeEndNotSelected: 'Route end not selected',
        routeStartNotSelected: 'Route start not selected',
        noData: 'No data',
        noAvialableRoutes: 'No avialable routes',
        nameNotChoosed: 'Name not choosed',
        notSelected: 'Not selected',
        notSet: 'Not set',
        sessionEnd: 'Current session finished',
        authSucc: 'You have been authorized successfully',
        authErr: 'Invalid login and(or) password',
        login: 'Login',
        exit: 'Exit',
        minute: 'min.',
        transArrived: 'arrived'
    }
};

// $.ready handler
$(document).ready(function() {
    // links to page objects
    var objects = {
        body : $('body'),
        alertbox: $('#alertbox'),
        map: document.getElementById('map_canvas'),
        onAuth : $('#auth'),
        control: $('#control'),
        editPoints: $('#edit_points'),
        editRoutes: $('#edit_routes'),
        editGuide: $('#edit_guide'),
        pointEditor: {
            open: $('#open-point-editor'),
            close: $('#point-editor-close'),
            save: $('#point-save'),
            remove: $('#point-delete'),
            valueLat: $('#label_posx'),
            valueLng: $('#label_posy'),
            valueTitle: $('#label_name')
        },
        routeEditor: {
            open: $('#open-route-editor'),
            close: $('#route-editor-close'),
            save: $('#route-save'),
            remove: $('#route-route-remove'),
            start: $('#button-route-start'),
            end: $('#button-route-end'),
            valueTitle: $('#route-name'),
            valueStart: $('#route-start'),
            valueEnd: $('#route-end')
        },
        guideEditor : {
            open: $('#open-guide'),
            close: $('#guide-close'),
            save: $('#guide-save'),
            create: $('#guide-new'),
            valueStart: $('#guide_start'),
            valueEnd: $('#guide_end'),
            valueLength: $('#guide_length'),
            valueUrl: $('#guide_url'),
            valueIfPlacesShowed: $('#guide-show-places')
        },
        toolBox: {
            base: $('#toolbox'),
            data: $('#toolbox-data'),
            activeGuide: $('#tab-guide-active'),
            activePoint: $('#tab-point-active'),
            activeRoute: $('#tab-route-active')
        },
        loginBox: {
            base: $('#authform'),
            login: $('#auth-login'),
            pass: $('#<PASSWORD>'),
            act: $('#auth-submit')
        },
        searchBar: {
            base: $('#main-search'),
            chosen: $('.chosen'),
            option: function() {
                return $('option');
            },
            groups: $('optgroup'),
            main: function() {
                return $('#main_search_chzn');
            },
            drop: function() {
                return $('.chzn-drop');
            }
        }
    };

    // livecity settings
    var settings = {
        zoom: 15,
        center: new google.maps.LatLng(51.4982000,31.2893500),
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle,
            position: google.maps.ControlPosition.BOTTOM_LEFT
        },
        navigationControl: true,
        navigationControlOptions: {
            style: google.maps.NavigationControlStyle.SMALL
        },
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        lang: 'RU'
    };
    // create new city
    city = new Livecity(objects,settings);
    // init city
    city.init();
    // set update function with interval
    // TBD
    setInterval('city.update()',2000);
    // Edit stations click handler
    objects.pointEditor.open.click(function() { city.onEditPoint(); });
    // edit route handler
    objects.routeEditor.open.click(function () { city.onEditRoute();});
    // guide handler
    objects.guideEditor.open.click(function() {city.onEditGuide();});
    // Close edit panel handler
    objects.pointEditor.save.click(function () {city.onSavePoint();});
    // Cancel edit point click handler
    objects.pointEditor.close.click(function () {city.onClosePointEditor();});
    // Cancel edit route click handler
    objects.routeEditor.close.click(function () {city.onCloseRouteEditor();});
    // Cancel guide
    objects.guideEditor.close.click(function() {city.onCloseGuideEditor();});
    // remove button click
    objects.pointEditor.remove.click(function () {city.onDeletePoint();});
    // back to city center
    objects.control.click(function (){city.setCenter();});
    // save route handler
    objects.routeEditor.save.click(function() { city.routeBuilder.save();});
    // set route start handler
    objects.routeEditor.start.click(function() {city.routeBuilder.setStart();});
    // set route start handler
    objects.routeEditor.end.click(function() {city.routeBuilder.setEnd();});
    // onAuth button handler
    objects.onAuth.click(function() {city.onAuth();});
    // login button handler
    objects.loginBox.base.on('submit', function(e) {city.onLogin(e)});
    // guide checkbox
    objects.guideEditor.valueIfPlacesShowed.change(function() {
        // check 'checked' property
        if (objects.guideEditor.valueIfPlacesShowed.prop('checked')) city.pointLayer.setVisible(true);
        else city.pointLayer.setVisible(false);
    });
    // new guide handler
    objects.guideEditor.create.click(function() {city.toolBox.__guideEditor.popAll();});
    // search bar init
    objects.searchBar.chosen.chosen({
            no_results_text: TEXT[city.getLang()],
    }).change(function() {
            city.searchBar.init($(this).val());
    });
    // fixing searchBar width... [TEMPORARY]
    objects.searchBar.main().css('width', '100%');
    objects.searchBar.drop().css('width', '100%');
    // key down handler
    objects.body.on('keydown',function(e) {
        // escape handler
        if (e.keyCode === 27) city.onEscape();
    });

    /*
     * TEXT SET
     */

    $.get('/app/version', function(version) {
        objects.control.html('livecity<div class="small"><sup> ' + version + '</sup></div> ');
    });
});

/*
 * City Class
 * @objects - link to HTML objects
 * @settings - settings for livecity
 */
function Livecity(objects,settings) {

    /*
     * PUBLIC ATTRIBUTES
     */

    // static - static functions and values
    this.static = {
        ICON_BLUE: function() {
            return new google.maps.MarkerImage('img/stop2.png', new google.maps.Size(16, 16), new google.maps.Point(0, 0), new google.maps.Point(8, 10));
        },
        ICON_RED: function() {
            return new google.maps.MarkerImage('img/stop-m2.png', new google.maps.Size(16, 16), new google.maps.Point(0, 0), new google.maps.Point(8, 10));
        },
        ICON_TRANS: function() {
            return new google.maps.MarkerImage('img/bus.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 33));
        },
        ICON_A: function() {
            return new google.maps.MarkerImage('http://www.google.com/mapfiles/markerA.png', new google.maps.Size(36, 36), new google.maps.Point(0, 0), new google.maps.Point(9, 33));
        },
        ICON_B: function() {
            return new google.maps.MarkerImage('http://www.google.com/mapfiles/markerB.png', new google.maps.Size(36, 36), new google.maps.Point(0, 0), new google.maps.Point(9, 33));
        },
        TYPE_POST: 'POST',
        TYPE_JSON: 'JSON',
        TYPE_GET: 'GET',
        TYPE_DELETE: 'DELETE',
        TYPE_PUT: 'PUT'
    };

    /*
     *  PRIVATE ATTRIBUTES
     */

    // UID
    var __uid = null;
    // objects
    var __objects = objects;
    // set settings
    var __settings = settings;
    // map
    var __map = new google.maps.Map(__objects.map,__settings);

    /*
     * PUBLIC GETTERS & SETTERS
     */

    // GET uid
    this.getUID = function() {
        return __uid;
    };
    // SET uid
    this.setUID = function(uid) {
        __uid = uid;
    };
    // GET objects
    this.getObjects = function() {
        return __objects;
    };
    // SET objects
    this.setObjects = function(objs) {
        __objects = objs;
    };
    // GET selected object
    this.getObject = function(name) {
        return __objects[name];
    };
    // SET selected object
    this.setObject = function(name,value) {
        __objects[name] = value;
    };
    // GET property
    this.getProperty = function(name) {
        return __settings[name];
    };
    // SET property
    this.setProperty = function(name,value) {
        __settings[name] = value;
    };
    // GET settings
    this.getProperties = function() {
        return __settings;
    };
    // GET lang property
    this.getLang = function() {
        return __settings.lang;
    };
    // SET lang property
    this.setLang = function(lng) {
        __settings.lang = lng;
    };
    // GET map
    this.getMap = function() {
        return __map;
    };
    // notifier
    this.notifier = new Notifier(this);
    // point layer
    this.pointLayer = new PointLayer(this);
    // route layer
    this.routeLayer = new RouteLayer(this);
    // trans layer
    this.transLayer = new TransLayer(this);
    // search bar
    this.searchBar = new SearchBar(this);
    // tool box
    this.toolBox = new ToolBox(this);
    // auth box
    this.loginBox = new LoginBox(this);
}

// [P] init - init map [DEPRECATED]
Livecity.prototype.init = function() {
    // link to main document
    var link = this;
    // load points on map
    this.pointLayer.load(function() {
        link.routeLayer.load(function(){
            link.searchBar.update();
        });
    });
    // map click handler
    google.maps.event.addListener(this.getMap(), 'click', function(event) {
        // point editor mode
        if (link.toolBox.isPointEditorOpened()) {
            var point = link.addPoint(event.latLng);
            point.save(function() {
                link.pointLayer.add(point);
                link.pointLayer.setCurrent(point);
                link.searchBar.update();
                link.outMsg(TEXT[link.getLang()].pointSaved,"green");
            });
        }
        // guide editor mode
        if (link.toolBox.isGuideEditorOpened()) {
            // temporary
            link.toolBox.__guideEditor.push(event.latLng);
        }
    });
    this.toolBox.maximize(false);
    this.loginBox.checkAuthorization(function(res) {
        link.login(res);
    });
    this.update();
};

// [P] outMsg - show notification message
Livecity.prototype.outMsg = function(text,color) {
    this.notifier.msg(text,color);
};

// [P] onEscape - Escape button handler
Livecity.prototype.onEscape = function() {
    // point editor mode
    if (this.toolBox.isPointEditorOpened()) {
        if (this.pointLayer.getCurrent()) {
            this.pointLayer.setCurrent();
            this.toolBox.clear();
        }
        else this.onClosePointEditor();
    }
    if (this.toolBox.isRouteEditorOpened()) {
        this.onCloseRouteEditor();
    }
    if (this.toolBox.isGuideEditorOpened()) {
        if (!this.toolBox.__guideEditor.empty()) {
            this.toolBox.__guideEditor.popAll();
            this.toolBox.clear();
        }
        else this.onCloseGuideEditor();
    }
};

// [P] setEditPointData - set edits for editing marker
Livecity.prototype.setEditPointData = function(position, title, focus) {
    var lat = position.lat();
    var lng = position.lng();
    // UPD - add option Round?
    this.getObjects().pointEditor.valueLat.text(Number(lat).toFixed(4));
    this.getObjects().pointEditor.valueLng.text(Number(lng).toFixed(4));
    this.getObjects().pointEditor.valueTitle.val(title);
    // UPD
    if (focus) this.getObjects().pointEditor.valueTitle.focus();
};

// [P] addPoint - add new point on map
Livecity.prototype.addPoint = function(position) {
    var title = "id" + (this.pointLayer.points.length);
    var point = new MapPoint(this, null, position, this.static.ICON_RED(), title);
    point.getMarker().setDraggable(true);
    point.setVisible(true);
    this.setEditPointData(position, title, true);
    return point;
};

// [P] setCenter - set map to selected map position
Livecity.prototype.setCenter = function(center) {
    // if center is not selected, set map center default value
    if (!center) {
        this.getMap().setCenter(this.getProperty('center'));
        this.outMsg(TEXT[this.getLang()].backToDefaultPlace,"green");
    }
    // if selected - set value and save to settings
    else {
        this.getMap().setCenter(center);
        this.setProperty('center',center);
    }
};

// [P] login - prepare view for authorized/unauthorized user
Livecity.prototype.login = function(is) {
    if (true === is) {
        this.toolBox.show(true);
        this.getObjects().onAuth.css("background", "url('img/lock.png') right no-repeat");
        this.getObjects().onAuth.text(TEXT[this.getLang()].exit);
        this.loginBox.setVisible(false);
    }
    else {
        this.toolBox.show(false);
        if (this.toolBox.isRouteEditorOpened()) this.onCloseRouteEditor();
        if (this.toolBox.isPointEditorOpened()) this.onClosePointEditor();
        if (this.toolBox.isGuideEditorOpened()) this.onCloseGuideEditor();
        this.getObjects().onAuth.css("background", "url('img/key.png') right no-repeat");
        this.getObjects().onAuth.text(TEXT[this.getLang()].login);
    }
};

// [P] onAuth - authorize user/end session
Livecity.prototype.onAuth = function() {
    var _this = this;
    this.loginBox.checkAuthorization(function(res) {
        if (true === res) {
            _this.loginBox.logout(function(res){
                if (true === res) {
                    _this.login(false);
                    _this.outMsg(TEXT[_this.getLang()].sessionEnd,"green");
                }
                else {
                    // TBD
                    // logout err
                }
            })
        }
        else {
            _this.loginBox.setVisible(true);
        }
    });
};

Livecity.prototype.onLogin = function(e) {
    var _this = this;
    this.loginBox.login(this.getObjects().loginBox.base, function(result){
        if (true === result) {
            _this.login(true);
            _this.outMsg(TEXT[_this.getLang()].authSucc,"green");
        }
        else {
            _this.login(false);
            _this.outMsg(TEXT[_this.getLang()].authErr, "red");
        }
    });
    e.preventDefault();
};

// [P] update - update trans layer on a map
Livecity.prototype.update = function() {
    this.transLayer.update();
};

// [P] onSavePoint - save point handler [DEPRECATED]
Livecity.prototype.onSavePoint = function() {
    var link = this;
    var current = this.pointLayer.getCurrent();
    if (!current) this.outMsg(TEXT[this.getLang()].noDataToSave,"red");
    else {
        current.save(function () {
            link.searchBar.update();
            link.outMsg(TEXT[link.getLang()].pointSaved,"green");
        });
{'fraction_non_alphanumeric': 0.1469310727016745, 'fraction_numerical': 0.005062456939160651, 'mean_word_length': 2.2803380170973764, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1639167', 'n_tokens_mistral': 10067, 'n_tokens_neox': 9935, 'n_words': 2018}