var Zoom = new function()
{
    var me_ = this;
    this.actual_level_ = 0;
    this.onzoom = new Array();

    this.init = function()
    {
        var zoomer = document.getElementById( 'zoomer' );
        var zr = document.getElementById( 'zr' );

        if ( zoom_levels_.length == 1 )
        {
            zoomer.style.display = 'none';
            return;
        }

        for( var i = 0; i < zoom_levels_.length; ++i )
        {
            var _z = document.createElement( 'img' );
            _z.src = 'img/zoomlevel.jpg';
            _z.id = "zoom_level_" + i;
            _z.alt = '';
            zoomer.insertBefore( _z, zr );
            addEvent( _z, 'click', function(e){ me_.on_zoom(e) }, false );
        }
        addEvent( document.getElementById('zi'), 'click', me_.increase, false, true );
        addEvent( document.getElementById('zd'), 'click', me_.decrease, false, true );
    }

    this.on_zoom = function(e)
    {
        e = standard_event( e );
        me_.set_zoom_level( e.target.id.substr(11) );
    }

    this.increase = function()
    {
        if ( me_.actual_level_ > 0 )
            me_.set_zoom_level( Number(me_.actual_level_) - 1 );
    }

    this.decrease = function()
    {
        if ( me_.actual_level_ + 1 < zoom_levels_.length )
            me_.set_zoom_level( Number(me_.actual_level_) + 1 );
    }

    this.set_zoom_level = function ( level )
    {
        if ( level == this.actual_level_ )
            return;
        this.actual_level_ = level;

        var z = document.getElementById( 'zoom_act' );
        var z_el = document.getElementById( 'zoom_level_' + this.actual_level_ );
        if ( z && z_el )
            z.style.left = z_el.offsetLeft + Math.round( ( z_el.offsetWidth - z.offsetWidth ) / 2 ) + 'px';

        for( var i = 0; i < this.onzoom.length; ++i )
            this.onzoom[i]();
    }

    this.width = function() { return zoom_levels_[ this.actual_level_ ][ 0 ]; }
    this.height = function() { return zoom_levels_[ this.actual_level_ ][ 1 ]; }
    this.scaleX = function() { return zoom_levels_[0][0] / zoom_levels_[ this.actual_level_ ][0]; }
    this.scaleY = function() { return zoom_levels_[0][1] / zoom_levels_[ this.actual_level_ ][1]; }
    this.tile_size = function() { return zoom_levels_[ this.actual_level_ ][ 2 ]; }
}();

addEvent( self, 'load', Zoom.init, false, true );

var sidebar = new function() {
    var me_ = this;
    var elm_ = null;
    var view_ = null;
    var menu_ = null;

    this.on_resize = function()
    {
        elm_.style.height = view_.offsetHeight - 20 - minimap_height_ + 'px';
        menu_.style.width = elm_.offsetWidth + view_.offsetWidth + 8 + 'px';
    }

    this.init = function()
    {
        elm_ = document.getElementById( 'sidebar' );
        view_ = document.getElementById( 'viewport' );
        menu_ = document.getElementById( 'menu' );
        addEvent( self, 'resize', function() { sidebar.on_resize() }, false, true );
        me_.on_resize();
    }
}();

addEvent( self, "load", function() { sidebar.init() }, false, true );

function RollUp( elm_id, unr ) {
    var me_ = this;
    var elm_ = null;
    var header_ = null;
    var img_ = null;
    var unrolled_ = true;

    this.toggle = function()
    {
        if ( unrolled_ == true )
            me_.rollup();
        else
            me_.unroll();
    }

    this.rollup = function()
    {
        elm_.style.overflow = 'hidden';
        elm_.style.height = header_.offsetHeight + 'px';
        img_.src = 'img/show.gif';
        unrolled_ = false;
    }

    this.unroll = function()
    {
        elm_.style.overflow = 'auto';
        elm_.style.height = 'auto';
        img_.src = 'img/hide.gif';
        unrolled_ = true;
    }

    elm_ = document.getElementById( elm_id );
    header_ = elm_.getElementsByTagName( 'p' )[0];
    img_ = header_.getElementsByTagName( 'img' )[0];
    unr ? this.unroll : this.rollup();
    addEvent( img_, 'click', this.toggle, false );
}

var rollup_connector = new function() {
    var me_ = this;
    this.search = null;
    this.street = null;
    this.cat = null;
    this.item = null;

    this.init = function()
    {
        me_.search = new RollUp( 'search_form' );
        me_.street = new RollUp( 'street_cont' );
        me_.cat = new RollUp( 'cat_cont', true );
        me_.item = new RollUp( 'item_cont' );
    }
}();

addEvent( self, "load", rollup_connector.init, false, true );

var Map = new function()
{
    var me_ = this;
    var tiles_= null;
    var view_ = null;
    var observer_ = new Array();
    var slide_timer_ = null;

    this.init = function()
    {
        view_ = document.getElementById( 'viewport' );
        tiles_ = document.getElementById( 'tiles' );

        set_map_dimensions();
        //me_.move_map_to( ( view_.offsetWidth  - Zoom.width() ) / 2, ( view_.offsetHeight - Zoom.height() ) / 2 );
        me_.center_view();
        check_tiles();
    }

    var check_tiles = function()
    {
        var x_begin = Math.max( Math.round( Math.abs( tiles_.offsetLeft ) / Zoom.tile_size() - 0.5 ), 0 );
        var y_begin = Math.max( Math.round( Math.abs( tiles_.offsetTop ) / Zoom.tile_size() - 0.5 ), 0 );
        var x_end = Math.min( Math.round( view_.offsetWidth/Zoom.tile_size() + 1.5 ) + x_begin, Zoom.width()/Zoom.tile_size() );
        var y_end = Math.min( Math.round( view_.offsetHeight/Zoom.tile_size() + 1.5 ) + y_begin, Zoom.height()/Zoom.tile_size() );

        for ( var x = x_begin; x < x_end; ++x )
            for ( var y = y_begin; y < y_end; ++y )
                show_tile( x, y );
    }

    var show_tile = function( x, y )
    {
        var tile_id = "z" + Zoom.actual_level_ + "y" + y + "x" + x;
        var mapped_tile = document.getElementById( tile_id );
        if ( !mapped_tile )
        {
            setTimeout( function() {
                mapped_tile = document.createElement( "img" );
                mapped_tile.className = 'tile';
                mapped_tile.src = 'maps/' + path_ + "/tiles/" + tile_id + tiles_ext_;
                mapped_tile.alt = '';
                mapped_tile.style.left = x * Zoom.tile_size() + "px";
                mapped_tile.style.top = y * Zoom.tile_size() + "px";
                mapped_tile.setAttribute( "id", tile_id );
                tiles_.appendChild( mapped_tile );
            }, 10 );
        }
    }

    this.on_resize = function()
    {
        notify( 'resize' );
        check_tiles();
    }

    this.on_zoom = function()
    {
        var x = ( view_.offsetWidth / 2 - tiles_.offsetLeft ) / tiles_.offsetWidth;
        var y = ( view_.offsetHeight / 2 - tiles_.offsetTop ) / tiles_.offsetHeight;
        remove_tiles();
        set_map_dimensions();
        set_position( view_.offsetWidth / 2 - x * Zoom.width(), view_.offsetHeight / 2 - y * Zoom.height() );
    };

    var remove_tiles = function()
    {
        var tiles = tiles_.getElementsByTagName( "img" );
        for( var i = 0; i < tiles.length; )
        {
            if ( tiles[i].className == 'tile' )
                tiles_.removeChild( tiles[ i ] );
            else
                ++i;
        }
    }

    var set_map_dimensions = function()
    {
        tiles_.style.width = Zoom.width() + 'px';
        tiles_.style.height = Zoom.height() + 'px';
        notify( 'resize' );
    }

    var notify = function( msg )
    {
        for( var i = 0; i < observer_.length; ++i )
            observer_[i]( msg );
    }

    this.move_map_to = function( x, y )
    {
        if ( x < view_.offsetWidth - Zoom.width() )
            x = view_.offsetWidth - Zoom.width();
        else if ( x + tiles_.offsetWidth > Zoom.width() )
            x = Zoom.width() - tiles_.offsetWidth;

        if ( y < view_.offsetHeight - Zoom.height() )
            y = view_.offsetHeight - Zoom.height();
        else if ( y + tiles_.offsetHeight > Zoom.height() )
            y = Zoom.height() - tiles_.offsetHeight;

        if ( slide_timer_ )
            clearTimeout( slide_timer_ );
        if ( Math.abs(x - tiles_.offsetLeft) < Zoom.tile_size() + view_.offsetWidth &&
            Math.abs(y - tiles_.offsetTop) < Zoom.tile_size() + view_.offsetHeight )
            slide_timer_ = setTimeout( slide_to( x, y, 1 ), 50 );
        else
            set_position( x, y );
    }

    var slide_to = function( x, y, step )
    {
        return function()
        {
            var next_x = Math.abs(x - tiles_.offsetLeft) > 10 ?
                step*(x - tiles_.offsetLeft)/20 + tiles_.offsetLeft : x;

            var next_y = Math.abs(y - tiles_.offsetTop) > 10 ?
                step*(y - tiles_.offsetTop)/20 + tiles_.offsetTop : y;
            set_position( next_x, next_y );

            if ( step < 20 && ( x != next_x || y != next_y ) )
                slide_timer_ = setTimeout( slide_to( x, y, ++step ), 50 );
        }
    }

    var set_position = function( x, y )
    {
        if ( x < view_.offsetWidth - Zoom.width() )
            x = view_.offsetWidth - Zoom.width();
        else if ( x + tiles_.offsetWidth > Zoom.width() )
            x = Zoom.width() - tiles_.offsetWidth;

        if ( y < view_.offsetHeight - Zoom.height() )
            y = view_.offsetHeight - Zoom.height();
        else if ( y + tiles_.offsetHeight > Zoom.height() )
            y = Zoom.height() - tiles_.offsetHeight;

        tiles_.style.left = x + 'px';
        tiles_.style.top = y + 'px';
        check_tiles();
        notify( 'move' );
    }

    this.center_to = function( x, y )
    {
        me_.move_map_to( view_.offsetWidth / 2 - x * Zoom.width(),
                    view_.offsetHeight / 2 - y * Zoom.height() );
    }

    this.center_view = function()
    {
        if ( center )
            me_.center_to( center.x, center.y );
        else
            me_.move_map_to( view_.offsetWidth/2 - Zoom.width()/2, view_.offsetHeight/2 - Zoom.height()/2 );
    }

    this.addObserver = function(fn){ observer_.push( fn ) }

    this.dragElement = function() { return tiles_ }
    this.dragHandle = function() { return tiles_ }
    this.dragStopOnOut = function() { return true }
    this.minX = function() { return view_.offsetWidth - Zoom.width() }
    this.minY = function() { return view_.offsetHeight - Zoom.height() }
    this.maxX = function() { return Zoom.width() }
    this.maxY = function() { return Zoom.height() }
    this.on_drag = function() { check_tiles(); notify( 'move' ) }
    this.move_up = function() { me_.move_map_to( tiles_.offsetLeft, tiles_.offsetTop + Zoom.tile_size() / 2 ) }
    this.move_left = function() { me_.move_map_to( tiles_.offsetLeft + Zoom.tile_size() / 2, tiles_.offsetTop ) }
    this.move_right = function() { me_.move_map_to( tiles_.offsetLeft - Zoom.tile_size() / 2, tiles_.offsetTop ) }
    this.move_down = function() { me_.move_map_to( tiles_.offsetLeft, tiles_.offsetTop - Zoom.tile_size() / 2 ) }

    this.move_up_y = function(y) { me_.move_map_to( tiles_.offsetLeft, tiles_.offsetTop - y ) }
    this.move_left_x = function(x) { me_.move_map_to( tiles_.offsetLeft - x, tiles_.offsetTop ) }
    this.move_right_x = function(x) { me_.move_map_to( tiles_.offsetLeft + x, tiles_.offsetTop ) }
    this.move_down_y = function(y) { me_.move_map_to( tiles_.offsetLeft, tiles_.offsetTop + y ) }

    this.X = function() { return ( view_.offsetWidth / 2 - tiles_.offsetLeft ) / tiles_.offsetWidth; }
    this.Y = function() { return ( view_.offsetHeight / 2 - tiles_.offsetTop ) / tiles_.offsetHeight; }
}();

addEvent( self, 'load', function() { Map.init(); Dragger.register( 'tiles', Map ); Zoom.onzoom.push( Map.on_zoom ) }, false, true );
addEvent( self, 'resize', Map.on_resize, false, true );

var Minimap = new function()
{
    var me_ = this;
    var tiles_ = null;
    var view_ = null;
    var map_ = null;
    var clip_ = null;
    var clip2_ = null;

    this.init = function()
    {
        tiles_ = document.getElementById( 'tiles' );
        view_ = document.getElementById( 'viewport' );
        map_ = document.getElementById( 'minimap' );
        clip_ = document.getElementById( 'miniclip' );
        clip2_ = document.getElementById( 'miniclip2' );
        Dragger.register( 'miniclip2', me_ );
        Map.addObserver( me_.draw );
        addEvent( map_, 'click', me_.on_click, false, true );
        me_.draw();
    }

    this.dragElement = function() { return clip2_ }
    this.dragHandle = function() { return clip2_ }
    this.dragOnParent = function() { return true }
    this.minX = function() { return map_.offsetLeft }
    this.minY = function() { return map_.offsetTop }
    this.maxX = function() { return map_.offsetWidth + map_.offsetLeft }
    this.maxY = function() { return map_.offsetHeight + map_.offsetTop }
    this.on_drag_end = function()
    {
        Map.move_map_to( ( map_.offsetLeft - clip2_.offsetLeft ) * scaleX(),
            ( map_.offsetTop - clip2_.offsetTop ) * scaleY() );
    }

    this.on_click = function( e )
    {
        e = standard_event( e );
        Map.move_map_to( view_.offsetWidth / 2 - e.layerX * scaleX(), view_.offsetHeight / 2 - e.layerY * scaleY() );
    }

    this.draw = function()
    {
        var x = map_.offsetLeft - Math.round( tiles_.offsetLeft / scaleX() ) + 'px';
        clip_.style.left = x;
        clip2_.style.left = x;

        var y = map_.offsetTop - Math.round( tiles_.offsetTop / scaleY() ) + 'px';
        clip_.style.top = y;
        clip2_.style.top = y;

        var w = Math.round( view_.offsetWidth / scaleX() ) + 'px';
        clip_.style.width = w;
        clip2_.style.width = w;

        var h = Math.round( view_.offsetHeight / scaleY() ) + 'px';
        clip_.style.height = h;
        clip2_.style.height = h;
    }
    var scaleX = function(){ return Zoom.width() / map_.offsetWidth }
    var scaleY = function(){ return Zoom.height() / map_.offsetHeight }
}();

addEvent( self, 'load', Minimap.init, false, true );

var DataLoader = new function()
{
    var me_ = this;
    var conn_ = new XHConn();
    var item_list_ = null;
    var cat_name_ = null;
    var active_category_ = null;
    var tiles_ = null;
    var minimap_ = null;

    this.init = function()
    {
        item_list_ = document.getElementById( 'item_list' );
        cat_name_ = document.getElementById( 'cat_name' );
        tiles_ = document.getElementById( 'tiles' );
        minimap_ = document.getElementById( 'minimap_cont' );
        me_.create_street_list();
        conn_.connect( "getcats.php", "GET", "", me_.on_categories_loaded );
        Zoom.onzoom.push( me_.remap_items );
    }

    this.create_street_list = function()
    {
        var sdv = document.getElementById( 'sdv' );
        for( var c = 'A'.charCodeAt(0); c <= 'Z'.charCodeAt(0); ++c )
        {
            var _span = document.createElement( 'span' );
            sdv.appendChild( _span );
            _span.appendChild( document.createTextNode( String.fromCharCode( c ) ) );
            _span.street = String.fromCharCode( c );
            addEvent( _span, 'click', me_.select_street_list, false, false );
            if ( c == 'M'.charCodeAt(0) )
                sdv.appendChild( document.createElement( 'br' ) );
        }
    }

    this.on_categories_loaded = function( request )
    {
        var _ul = document.getElementById( 'cat_list' );
        var cats = eval( "(" + request.responseText + ")" );
        for( var i = 0; i < cats.length; ++i )
        {
            var _li = document.createElement( 'li' );
            _ul.appendChild( _li );
            _li.appendChild( document.createTextNode( cats[i].name ) );
            _li.title = cats[i].description;
            _li.className = 'sidebar_li';
            _li.category = cats[i];
            addEvent( _li, 'click', function(e) { e = standard_event(e); me_.select_category( e.target ) }, false, false );
        }
        me_.select_category( _ul.firstChild );
    }

    this.select_street_list = function( e )
    {
        e = standard_event(e);
        me_.set_category_name( 'Straßenliste' );
        conn_.connect( "getstreets.php", "GET", "q=" + e.target.street + "&map_id=" + map_id_, me_.on_items_loaded );
    }

    this.select_category = function( _li )
    {
        active_category_ = _li;
        me_.set_category_name( active_category_.category.name )
        active_category_.className = 'sidebar_li active';

        conn_.connect( "getitems.php", "GET", "cat_id=" + active_category_.category.cat_id + "&map_id=" + map_id_, me_.on_items_loaded );
    }

    this.set_category_name = function( name )
    {
        remove_all_childs( cat_name_ );
        cat_name_.appendChild( document.createTextNode( name ) );
    }

    var remove_all_childs = function( elm )
    {
        while( elm.firstChild )
            elm.removeChild( elm.firstChild );
    }

    this.on_items_loaded = function( request )
    {
        clear( true );
        var items = eval( "(" + request.responseText + ")" );
        for( var i in items )
        {
            var item = items[i];
            var _li = document.createElement( 'li' );
            item_list_.appendChild( _li );
            _li.appendChild( document.createTextNode( item.name ) );
            _li.className = 'sidebar_li';
            _li.item = item;
            addEvent( _li, 'click', me_.select_item, false, false );

            create_item( item );
            for ( var i in item.locations )
            {
                var subitem = item.locations[i];

                if ( item.image && ! subitem.image )
                    subitem.image = item.image;
                if ( item.text && ! subitem.text )
                    subitem.text = item.text;
                if ( item.web && ! subitem.web )
                    subitem.web = item.web;

                var _lsi = document.createElement( 'li' );
                item_list_.appendChild( _lsi );
                _lsi.appendChild( document.createTextNode( subitem.name ) );
                _lsi.className = 'sidebar_li sidebar_lsi';
                _lsi.item = subitem;
                addEvent( _lsi, 'click', me_.select_item, false, false );

                create_item( subitem );
            }
        }
        rollup_connector.item.unroll();
        rollup_connector.street.rollup();
        rollup_connector.cat.rollup();
    }

    var clear = function( all )
    {
        if ( all )
        {
            remove_all_childs( item_list_ );

            if ( active_category_ )
                active_category_.className = 'sidebar_li';
            remove_elements( minimap_, 'img', 'minimap_item' );
        }
        remove_elements( tiles_, 'p', 'wimpel' );
        remove_elements( tiles_, 'p', 'wimpel ho' );
        remove_elements( tiles_, 'img', 'wimarr' );
//      remove_elements( tiles_, 'div', 'info_cont' );
        document.getElementById( 'ring' ).style.left = '20000px';
    }

    this.remap_items = function()
    {
        clear( false );
        var items = item_list_.getElementsByTagName( 'li' );
        for( var i = 0; i < items.length; ++i )
            create_item( items[i].item );
    }

    var hide_items = function()
    {
        document.getElementById( 'ring' ).style.left = '20000px';
        var infos = tiles_.getElementsByTagName( 'div' );
//      for( var i = 0; i < infos.length; ++i )
//          if ( infos[i].className == 'info_cont' )
//              infos[i].style.visibility = 'hidden';
    }

    var show_street = function( item )
    {
        var street_item_ = document.getElementById( 'ring' );
        street_item_.style.left = item.left * Zoom.width() - 30 + 'px';
        street_item_.style.top = item.top * Zoom.height() - 30 + 'px';
    }

    this.show_text = function( a, t )
    {
//      a.style.display = 'none';
        t.style.display = 'block';
    }

    var create_picture = function( info_el, item )
    {
        if ( show_picture(item) )
        {
            var _ads = document.createElement( 'div' );
            info_el.appendChild( _ads );
            _ads.className = 'info_ads';
            _ads.id = 'info_ads_' + item.id;

            var ads_img = document.createElement( 'img' );
            _ads.appendChild( ads_img );
            ads_img.src = item.image;
            ads_img.alt = '';
            return ads_img;
        }
        return null;
    }

    var create_text = function( info_el, item )
    {
        var _text = document.createElement( 'div' );
        info_el.appendChild( _text );
        _text.className = 'info_text';
        _text.id = 'info_text_' + item.id;
        _text.innerHTML = item.text;
        _text.style.display = show_picture(item) ? 'none' : 'block';
    }

    var create_web_menu_item = function( item )
    {
        var e = document.createElement( show_web(item) ? 'a' : 'span' );
        e.appendChild( document.createTextNode( "Webseite" ) );
        if ( show_web( item ) )
        {
            e.href = item.web;
            e.target = '_blank';
        }
        else
            e.className = 'inactive_menu';
        return e;
    }

    var create_text_menu_item = function( item )
    {
        var e = document.createElement( 'span' );
        e.appendChild( document.createTextNode( "Aktuelles" ) );
        if ( show_text( item ) )
        {
            $('info_text_' + item.id).style.display = show_picture(item) ? 'none' : 'block';
            addEvent( e, 'click', function()
            {
                if ( $('info_text_' + item.id).style.display == 'none' )
                    $('info_text_' + item.id).style.display = 'block';
                else
                    $('info_text_' + item.id).style.display = 'none';
                me_.ensure_visible( item.id );
            }
            , false, false );
        }
        else
            e.className = 'inactive_menu';
        return e;
    }

    var create_info = function( item )
    {
        var info_el = document.createElement( 'div' );
        tiles_.appendChild( info_el );
        info_el.id = 'info_' + item.id;
        info_el.className = 'info_cont';
        info_el.toggle = false;
        info_el.item = item;

        var img = create_picture( info_el, item );

        if ( show_text(item) )
            create_text( info_el, item );

        var _menu = document.createElement( 'div' );
        info_el.appendChild( _menu );
        _menu.className = 'info_menu';

        _menu.appendChild( create_web_menu_item( item ) );
        _menu.appendChild( create_text_menu_item( item ) );

        var _a4 = document.createElement( 'span' );
        _menu.appendChild( _a4 );
        _a4.className = 'fr';
        _a4.appendChild( document.createTextNode( "Schließen" ) );
        addEvent( _a4, 'click', function() { info_el.style.visibility = 'hidden' }, false, false );

        if ( item.left < 0.5 && item.top < 0.5 )
        {
            info_el.style.left = item.left * Zoom.width() + 'px';
            info_el.style.top = item.top * Zoom.height() + 'px';
        }
        else if ( item.left > 0.5 && item.top < 0.5 )
        {
            info_el.style.right = ( 1 - item.left ) * Zoom.width() + 'px';
            info_el.style.top = item.top * Zoom.height() + 'px';
        }
        else if ( item.left > 0.5 && item.top > 0.5 )
        {
            info_el.style.right = ( 1 - item.left ) * Zoom.width() + 'px';
            info_el.style.bottom = ( 1 - item.top ) * Zoom.height() + 'px';
        }
        else
        {
            info_el.style.left = item.left * Zoom.width() + 'px';
            info_el.style.bottom = ( 1 - item.top ) * Zoom.height() + 'px';
        }
        //setTimeout( function(){ me_.adjust_position(info_el, img); }, 100 );
        return info_el;
    }

    this.ensure_visible = function( id )
    {
        if ( $( 'info_ads_' + id) )
        {
            if ( $( 'info_ads_' + id).offsetWidth > 0 )
            {
                var info_el = $( 'info_' + id);
                var x = 0;
                var y = 0;
                if ( info_el.offsetLeft < 20 - tiles_.offsetLeft )
                    x = 20 - info_el.offsetLeft - tiles_.offsetLeft;
                else if ( info_el.offsetLeft + info_el.offsetWidth >  $('viewport').offsetWidth - tiles_.offsetLeft - 20 )
                    x = $('viewport').offsetWidth - info_el.offsetLeft - info_el.offsetWidth - tiles_.offsetLeft - 20;
                if ( info_el.offsetTop < 20 - tiles_.offsetTop )
                    y = 20 - info_el.offsetTop - tiles_.offsetTop;
                else if ( info_el.offsetTop + info_el.offsetHeight >  $('viewport').offsetHeight - tiles_.offsetTop - 20 )
                    y = $('viewport').offsetHeight - info_el.offsetTop - info_el.offsetHeight - tiles_.offsetTop - 20;

                Map.move_map_to( tiles_.offsetLeft + x, tiles_.offsetTop + y )
            }
            else
                setTimeout( function(){ me_.ensure_visible(id); }, 100 );
        }
    }

    var toggle_info = function( id )
    {
        $('info_' + id).style.visibility = 'visible';
        me_.ensure_visible( id );
    }

    this.select_item = function( e )
    {
        e = standard_event(e);
        hide_items();
        var item = e.target.item;
        if ( item )
        {
            if ( item.type == 'street' )
            {
                show_street( item );
            }
            else if ( show_picture(item) || show_text(item)  )
            {
                if ( $('info_' + item.id) )
                {
                    toggle_info( item.id );
                    return;
                }
                else
                {
                    info_el = create_info( item );
                    if ( e.target.tagName == "P" )
                    {
                        toggle_info( item.id );
                        return;
                    }
                }
            }
            Map.center_to( item.left, item.top );
        }
    }

    var create_minimap_item = function( item )
    {
        var _img = document.createElement( "img" );
        minimap_.appendChild( _img );
        _img.className = 'minimap_item';
        _img.src = 'img/item.gif';
        _img.alt = item.name;
        _img.title = item.name;
        _img.item = item;
        _img.style.top = Math.min( Math.round( minimap_height_ * item.top ), minimap_height_ - 6 ) + 'px';
        _img.style.left = Math.min( Math.round( 260 * item.left ), 254 ) + 'px';
        addEvent( _img, 'click', me_.select_item, false, false );
    }

    var create_wimpel_arrow = function( item )
    {
        var _arr = document.createElement( 'img' );
        tiles_.appendChild( _arr );
        _arr.src = 'img/arr.gif';
        _arr.alt = '';
        _arr.style.left = Math.min( item.left * Zoom.width(), Zoom.width() - 15 ) + 'px';
        _arr.style.top = Math.min( item.top * Zoom.height(), Zoom.height() - 15 ) + 'px';
        _arr.className = 'wimarr';
    }

    var show_web = function( item ) {
        return !(item.state & 4) && (item.state & 8) && item.web && item.web != '';
    }

    var show_picture = function( item ) {
        return !(item.state & 4) && (item.state & 16) && item.image && item.image != '';
    }

    var show_text = function( item ) {
        return !(item.state & 4) && (item.state & 32) && item.text && item.text != '';
    }

    var create_item = function( item )
    {
        if ( item.type == 'street' )
            return;
        create_minimap_item( item );
        create_wimpel_arrow( item );

        var _w = document.createElement( 'p' );
        tiles_.appendChild( _w );
        _w.item = item;

        if ( ! show_web(item) && ! show_picture(item) && ! show_text(item) )
        {
            _w.className = 'wimpel';
            _w.appendChild( document.createTextNode( item.name ) );
        }
        else
        {
            _w.style.cursor = 'pointer';
            _w.className = 'wimpel ho';
            if ( ! show_picture(item) && ! show_text(item) )
            {
                var _a3 = document.createElement( 'a' );
                _w.appendChild( _a3 );
                _a3.href = item.web;
                _a3.target = '_blank';
                _a3.title = item.web + " öffnen";
                _a3.appendChild( document.createTextNode( item.name ) );
            }
            else
            {
                _w.title = "Info anzeigen";
                _w.appendChild( document.createTextNode( item.name ) );
                addEvent( _w, 'click', me_.select_item, false, false );
            }
        }
        _w.style.left = Math.min( item.left * Zoom.width() + 15, Zoom.width() - _w.offsetWidth ) + 'px';
        _w.style.top = Math.min( item.top * Zoom.height() + 15, Zoom.height() - _w.offsetHeight ) + 'px';
    }

    var remove_elements = function( parent, tag, cls )
    {
        var elms = parent.getElementsByTagName( tag );
        for( var i = 0; i < elms.length; )
        {
            if ( elms[i].className == cls )
                parent.removeChild( elms[i] );
            else
                ++i;
        }
    }
}();

addEvent( self, 'load', DataLoader.init, false, true );

var Search = new function()
{
    var me_ = this;
    var query_= null;
    var timeout_ = null;

    this.init = function()
    {
        query_ = document.getElementById( 'query' );
        addEvent( query_, 'change', function(e){ me_.on_change(e) }, false, false );
        addEvent( query_, 'keypress', function(e){ me_.on_change(e) }, false, false );
        var btn = document.getElementById( 'query_btn' );
        addEvent( btn, 'click', function(e){ me_.on_query(e) }, false, false );
    }

    this.on_change = function()
    {
        if ( timeout_ )
        {
            clearTimeout( timeout_ );
            timeout_ = null;
        }
        if ( query_.value.length >= 2 )
            timeout_ = setTimeout( "Search.on_query()", 200 );
    }

    this.on_query = function()
    {
        var conn = new XHConn();
        DataLoader.set_category_name( "Suchergebnisse" );
        conn.connect( "getsearch.php", "GET", "q=" + query_.value + "&map_id=" + map_id_, DataLoader.on_items_loaded );
    }
}();

addEvent( self, 'load', Search.init, false, true );
addEvent( self, 'load', function()
{
    document.getElementById('minimap_cont').style.height = minimap_height_ + 'px';
}, false, true );

