

#include <locationlist.h>
#include <iwear/i18n.h>
#include <iwlocator/wlocation.h>
#include <locationdialog.h>

namespace iwear
{
    namespace sensor
    {
	namespace location
	{

LocationList::LocationList( QWidget* parent )
{
    setup();
}

LocationList::~LocationList( )
{
}

void LocationList::setup( void )
{
    setMinimumSize(80,80);
    setShowSortIndicator( TRUE );

    addColumn(i18n::trans("ID"),1);
    addColumn(i18n::trans("Probability"),1);
    addColumn(i18n::trans("Room"),1);
    addColumn(i18n::trans("Latitude"),1);
    addColumn(i18n::trans("Longitude"),1);
    addColumn(i18n::trans("Elevation"),1);

    setAllColumnsShowFocus( TRUE );

    setSorting(1,FALSE);
    for( int i = 0; i < 6; ++i )
    {
	adjustColumn(i);
    }

    update();
    connect(this, SIGNAL(doubleClicked(QListViewItem *, const QPoint &, int)), SLOT(location_info(QListViewItem *, const QPoint &, int)));
//    Location* test_loc = new Location;
//    new LocationListItem(this,test_loc,true);
}

void LocationList::location_info( QListViewItem* qlv, const QPoint&, int col )
{
    cout << "Double clicked item" << endl;
    if( qlv )
    {
	LocationListItem* lli = dynamic_cast<LocationListItem*>(qlv);
	if( ! lli )
	{
	    throw runtime_error("Something different in the list...");
	}
	const Location* loc = lli->get_location();
	map<const Location*, LocationDialog*>::iterator ldi(locdmap.find(loc));

	if( ldi == locdmap.end() )
	{
	    cout << "Did not find the location " << (void*)loc << " in the map" << endl;
	    LocationDialog* ld = new LocationDialog(loc,this);
	    ld->show();
	    locdmap.insert(make_pair(loc,ld));
	}
	else
	{
	    LocationDialog* ld = ldi->second;
	    ld->show();
	}
    }
}

void LocationList::update( void )
{
    /*
    QListViewItem* qlvi = NULL;
    while( (qlvi = lastItem()) )
    {
	takeItem(qlvi);
    }
    */
    clear();
    // Now list should be empty
    int n = locations.size();
    cout << "PAINTING " << n << " LOCATIONS" << endl;

    for( int i = 0; i < n; ++i )
    {
	const WLocation* wloc = dynamic_cast<const WLocation*>(locations[i]);
	map<const Location*, LocationDialog*>::iterator ldi(locdmap.find(locations[i]));
	if( ldi != locdmap.end() )
	{
	    cout << "UPDATING" << endl;
	    ldi->second->update(locations[i]);
	}
	cout << "UPDATING" << (void*)locations[i] << endl;
	if( wloc )
	{
	    new LocationListItem(this,locations[i],true);
	}
	else
	{
	    new LocationListItem(this,locations[i],false);
	}
    }
    sort();
    
    QListView::update();
    //triggerUpdate();
}

LocationListItem::LocationListItem( QListView* parent, const Location* loc, bool wlan )
    : QListViewItem( parent ),
    location(loc),
    wlanlocation(wlan)
{
    if( ! loc )
    {
	setText(0,"(null)");
	setText(1,"(null)");
	setText(2,"(null)");
	setText(3,"(null)");
    }
    else
    {
	setText(0,QString("%1").arg(loc->get_dbid()) );
	setText(1,QString("%1%").arg( 100.0*(1.0-min(loc->room_rms,loc->pos_rms))));
	setText(2,loc->room);
	if( loc->pos_lat >= 0.0 )
	{
	    setText(3,QString(i18n::trans("%1°N")).arg(loc->pos_lat));
	}
	else
	{
	    setText(3,QString(i18n::trans("%1°S")).arg(- loc->pos_lat));
	}

	if( loc->pos_lon >= 0.0 )
	{
	    setText(4,QString(i18n::trans("%1°E")).arg(loc->pos_lon));
	}
	else
	{
	    setText(4,QString(i18n::trans("%1°W")).arg(- loc->pos_lon));
	}

	setText(5,QString(i18n::trans("%1 meter")).arg(loc->pos_elev));
    }
}

void LocationListItem::paintCell( QPainter *p, const QColorGroup &cg,
				 int column, int width, int alignment )
{
    QColorGroup _cg( cg );
//    QColor c = _cg.text();

    if ( wlanlocation )
    {
	_cg.setColor( QColorGroup::Text, Qt::blue );
    }

    QListViewItem::paintCell( p, _cg, column, width, alignment );

 //   _cg.setColor( QColorGroup::Text, c );
}

int LocationListItem::compare ( QListViewItem * i, int col, bool ascending ) const
{
    LocationListItem* lli = dynamic_cast<LocationListItem*>(i);
    if( ! lli ) throw runtime_error("Cannot compare to different type");
    const Location* loc1 = get_location();
    const Location* loc2 = lli->get_location();

    switch( col )
    {
	case 0: // ID
	    return (loc1->get_dbid() < loc2->get_dbid());

	case 1: // Probability
	    return ( min(loc1->room_rms,loc1->pos_rms) > min(loc2->room_rms,loc2->pos_rms) );
//	case 2: // Room
	case 3: // Latitude
	    return ( loc1->pos_lat < loc2->pos_lat );
	case 4: // Longitude
	    return ( loc1->pos_lon < loc2->pos_lon );
	case 5:	// Elevation
	    return ( loc1->pos_elev < loc2->pos_elev );
	default:
	    return QListViewItem::compare ( i, col, ascending );
    }
}

void LocationList::set_list( const map<uint32_t,WLocation*>& lm )
{
    int n = lm.size();
    locations.resize(n);
    map<uint32_t,WLocation*>::const_iterator li(lm.begin());
    for( int i = 0; i < n; ++i, ++li )
    {
	locations[i] = li->second;
    }
}

void LocationList::set_list( const map<uint32_t,Location*>& lm )
{
    int n = lm.size();
    locations.resize(n);
    map<uint32_t,Location*>::const_iterator li(lm.begin());
    for( int i = 0; i < n; ++i, ++li )
    {
	locations[i] = li->second;
    }
}

void LocationList::add_list( const map<uint32_t,WLocation*>& lm )
{
    int ln = lm.size();
    int n = locations.size();
    int nm = ln+n;
    locations.resize(nm);
    
   cout << "Adding " << ln  << " Locations" << endl; 

    map<uint32_t,WLocation*>::const_iterator li(lm.begin());

    for( int i = n; i < nm; ++i, ++li )
    {
	cout << "Inserting at position " << i << endl;
	locations[i] = li->second;
    }   
    cout << "TOTAL : " << locations.size() << endl;
}

void LocationList::add_list( const map<uint32_t,Location*>& lm )
{
    return;
    int ln = lm.size();
    int n = locations.size();
    int nm = ln+n;
    locations.resize(nm);
   
    map<uint32_t,Location*>::const_iterator li(lm.begin());

    for( int i = n; i < nm; ++i, ++li )
    {
	locations[i] = li->second;
    }
}

void LocationList::set_list( const vector<Location*>& lv )
{
    int n = lv.size();
    locations.resize(n);
    for( int i = 0; i < n; ++i )
    {
	locations[i] = lv[i];
    }
}
	
}
}
}
