/***************************************************************************
                          mapcanvas.cpp  -  K Desktop Planetarium
                             -------------------
    begin                : Tue Apr 10 2001
    copyright            : (C) 2001 by Jason Harris
    email                : jharris@30doradus.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "mapcanvas.h"
#include <cstdlib>

#include <QPainter>
#include <QPixmap>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QStandardPaths>
#include "kspaths.h"


#include "dialogs/locationdialog.h"
#include "kstars.h"
#include "kstarsdata.h"

MapCanvas::MapCanvas( QWidget *parent ) :
    QFrame( parent ),
    ld(0)
{
    setAutoFillBackground( false );

    QString bgFile = KSPaths::locate(QStandardPaths::GenericDataLocation, "geomap.png" );
    bgImage = new QPixmap( bgFile );

    origin.setX( bgImage->width()/2 );
    origin.setY( bgImage->height()/2 );
}

MapCanvas::~MapCanvas(){
    delete bgImage;
}

void MapCanvas::setGeometry( int x, int y, int w, int h ) {
    QWidget::setGeometry( x, y, w, h );
    origin.setX( w/2 );
    origin.setY( h/2 );
}

void MapCanvas::setGeometry( const QRect &r ) {
    QWidget::setGeometry( r );
    origin.setX( r.width()/2 );
    origin.setY( r.height()/2 );
}

void MapCanvas::mousePressEvent( QMouseEvent *e ) {
    //Determine Lat/Long corresponding to event press
    int lng = ( e->x() - origin.x() );
    int lat  = ( origin.y() - e->y() );

    if( ld )
        ld->findCitiesNear( lng, lat );
}

void MapCanvas::paintEvent( QPaintEvent * ) {
    QPainter p;

    //prepare the canvas
    p.begin( this );
    p.drawPixmap( 0, 0, bgImage->scaled( size() ) );
    p.setPen( QPen( QColor( "SlateGrey" ) ) );

    //Draw cities
    QPoint o;
    foreach ( GeoLocation *g, KStarsData::Instance()->getGeoList() ) {
        o.setX( int( g->lng()->Degrees() + origin.x() ) );
        o.setY( height() - int( g->lat()->Degrees() + origin.y() ) );

        if ( o.x() >= 0 && o.x() <= width() && o.y() >=0 && o.y() <=height() ) {
            p.drawPoint( o.x(), o.y() );
        }
    }

    // FIXME: there must be better way to this. Without bothering LocationDialog
    if( ld ) {
        //redraw the cities that appear in the filtered list, with a white pen
        //If the list has not been filtered, skip the redraw.
        if ( ld->filteredList().size() ) {
            p.setPen( Qt::white );
            foreach ( GeoLocation *g, ld->filteredList() ) {
                o.setX( int( g->lng()->Degrees() + origin.x() ) );
                o.setY( height() - int( g->lat()->Degrees() + origin.y() ) );

                if ( o.x() >= 0 && o.x() <= width() && o.y() >=0 && o.y() <=height() ) {
                    p.drawPoint( o.x(), o.y() );
                }
            }
        }

        GeoLocation *g = ld->selectedCity();
        if ( g ) {
            o.setX( int( g->lng()->Degrees() + origin.x() ) );
            o.setY( height() - int( g->lat()->Degrees() + origin.y() ) );

            p.setPen( Qt::red );
            p.setBrush( Qt::red );
            p.drawEllipse( o.x()-3, o.y()-3, 6, 6 );
            p.drawLine( o.x()-16, o.y(), o.x()-8, o.y() );
            p.drawLine( o.x()+8, o.y(), o.x()+16, o.y() );
            p.drawLine( o.x(), o.y()-16, o.x(), o.y()-8 );
            p.drawLine( o.x(), o.y()+8, o.x(), o.y()+16 );
            p.setPen( Qt::white );
            p.setBrush( Qt::white );
        }
    }
    p.end();
}

