/* bubblewindow.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2015 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "bubblewindow.hh"
#include "acontainerbb.h"
#include "textview.h"

BubbleWindow::BubbleWindow( AGUIX *parent,
                            int x,
                            int y,
                            int width,
                            int height,
                            std::string title,
                            const Widget *linked_widget ) :
    AWindow( parent, x, y, width, height, title ),
    m_linked_widget( linked_widget )
{
    int tbg = _aguix->getFaces().getColor( "popup-bg" );

    if ( tbg >= 0 ) {
        _bg = tbg;
    }
}

BubbleWindow::~BubbleWindow()
{
    destroy();
}

void BubbleWindow::show()
{
    AWindow::show();
    toFront();
}

int BubbleWindow::create()
{
    int erg = AWindow::create();
    
    XSetWindowAttributes set_attr;
    set_attr.override_redirect = True;
    XChangeWindowAttributes( _aguix->getDisplay(), win, CWOverrideRedirect, &set_attr );
    
    return erg;
}

bool BubbleWindow::handleMessage( XEvent *e,Message *msg )
{
    bool res = AWindow::handleMessage( e, msg );

    if ( res == true ) return true;

    if ( ! m_linked_widget ) return false;

    if ( msg->type == ButtonPress ) {
        if ( isParent( msg->window, false ) ) {
            hide();
        }
    }

    return res;
}

bool BubbleWindow::ownedByLinkedWidget( Window w )
{
    if ( ! m_linked_widget ) return false;

    return m_linked_widget->isParent( w );
}

void BubbleWindow::unsetLinkedWidget()
{
    m_linked_widget = NULL;
}

static bool is_rectangle_within( int x1, int y1, int w1, int h1,
                                 int x2, int y2, int w2, int h2 )
{
    if ( x1 < x2 ) return false;

    if ( x1 + w1 > x2 + w2 ) return false;

    if ( y1 < y2 ) return false;

    if ( y1 + h1 > y2 + h2 ) return false;

    return true;
}

void BubbleWindow::prepareHelpText( const std::string &m_bubble_help_text )
{
    create();
    
    AContainerBB *ac0 = (AContainerBB *)setContainer( new AContainerBB( this, 1, 1 ), true );
    ac0->setMinSpace( 0 );
    ac0->setMaxSpace( 0 );
    ac0->setBorderWidth( 1 );
    ac0->setBBState( false );


    AContainer *ac1 = ac0->add( new AContainer( this, 1, 1 ), 0, 0 );
    ac1->setMinSpace( 0 );
    ac1->setMaxSpace( 0 );
    ac1->setBorderWidth( 5 );
    
    addMultiLineText( m_bubble_help_text,
                      *ac1,
                      0, 0,
                      NULL, NULL, true );

    ac1->readLimits();
    ac0->readLimits();
    contMaximize( true );

    Window root, child;
    int mouse_root_x, mouse_root_y, rel_x, rel_y;
    unsigned int buttons;

    XQueryPointer( _aguix->getDisplay(),
                   m_linked_widget->getWindow(),
                   &root,
                   &child,
                   &mouse_root_x, &mouse_root_y,
                   &rel_x, &rel_y,
                   &buttons );

    int linked_widget_x, linked_widget_y, linked_widget_width, linked_widget_height;

    linked_widget_x = mouse_root_x - rel_x;
    linked_widget_y = mouse_root_y - rel_y;

    linked_widget_width = m_linked_widget->getWidth();
    linked_widget_height = m_linked_widget->getHeight();

    // now try to place this window around the coordinates

    int root_x, root_y, root_w, root_h;
    
    _aguix->getLargestDimensionOfCurrentScreen( &root_x, &root_y, &root_w, &root_h );

#if 0
    // try south-east first
    if ( is_rectangle_within( linked_widget_x + linked_widget_width + 10,
                              linked_widget_y + linked_widget_height + 10,
                              getWidth(),
                              getHeight(),
                              root_x, root_y, root_w, root_h ) ) {
        move( linked_widget_x + linked_widget_width + 10,
              linked_widget_y + linked_widget_height + 10 );
    } else if ( is_rectangle_within( linked_widget_x - getWidth() - 10,
                                     linked_widget_y + linked_widget_height + 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // south-west
        move( linked_widget_x - getWidth() - 10,
              linked_widget_y + linked_widget_height + 10 );
    } else if ( is_rectangle_within( linked_widget_x - getWidth() - 10,
                                     linked_widget_y - getHeight() - 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // north-west
        move( linked_widget_x - getWidth() - 10,
              linked_widget_y - getHeight() - 10);
    } else if ( is_rectangle_within( linked_widget_x + linked_widget_width + 10,
                                     linked_widget_y - getHeight() - 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // north-east
        move( linked_widget_x + linked_widget_width + 10,
              linked_widget_y - getHeight() - 10 );
    } else
#endif
        if ( is_rectangle_within( mouse_root_x + 10,
                                  mouse_root_y + 10,
                                  getWidth(),
                                  getHeight(),
                                  root_x, root_y, root_w, root_h ) ) {
        // south-east of mouse
        move( mouse_root_x + 10,
              mouse_root_y + 10 );
    } else if ( is_rectangle_within( mouse_root_x - getWidth() - 10,
                                     mouse_root_y + 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // south-west of mouse
        move( mouse_root_x - getWidth() - 10,
              mouse_root_y + 10 );
    } else if ( is_rectangle_within( mouse_root_x - getWidth() - 10,
                                     mouse_root_y - getHeight() - 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // north-west of mouse
        move( mouse_root_x - getWidth() - 10,
              mouse_root_y - getHeight() - 10 );
    } else if ( is_rectangle_within( mouse_root_x + 10,
                                     mouse_root_y - getHeight() - 10,
                                     getWidth(),
                                     getHeight(),
                                     root_x, root_y, root_w, root_h ) ) {
        // north-east of mouse
        move( mouse_root_x + 10,
              mouse_root_y - getHeight() - 10 );
    } else {
        // fallback to south-east
        move( linked_widget_x + linked_widget_width + 10,
              linked_widget_y + linked_widget_height + 10 );
    }
}
