/*
 * Copyright (c) 1991 Stanford University
 * Copyright (c) 1991 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Stanford and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Stanford and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

/*
 * DialogKit -- object for creating common dialog boxes
 */


/* kandrews 14 Jul 94
 *
 * Avoid using DialogKit so do not need IV2.6 stuff
 * has been deleted from file
 */

#include <InterViews/dialog.h>



#include <IV-look/kit.h>

#include <InterViews/display.h>
#include <InterViews/event.h>
#include <InterViews/handler.h>
#include <InterViews/session.h>
#include <InterViews/style.h>
#include <InterViews/window.h>
#include <hyperg/OS/string.h>



/* class DialogHandler -- helper for class Dialog */

class DialogHandler : public Handler {
public:
    DialogHandler(Dialog*);
    virtual ~DialogHandler();

    virtual boolean event(Event&);
private:
    Dialog* dialog_;
};

DialogHandler::DialogHandler(Dialog* d) { dialog_ = d; }
DialogHandler::~DialogHandler() { }

boolean DialogHandler::event(Event&) {
    dialog_->dismiss(false);
    return true;
}



/* class Dialog */

Dialog::Dialog(Glyph* g, Style* s) : InputHandler(g, s) { }
Dialog::~Dialog() { }

boolean Dialog::post_for_aligned(Window* w, float x_align, float y_align) {
    TransientWindow* t = new TransientWindow(this);
    t->style(new Style(style()));
    t->transient_for(w);
    t->wm_delete(new DialogHandler(this));
    t->place(w->left() + 0.5 * w->width(), w->bottom() + 0.5 * w->height());
    t->align(x_align, y_align);
    t->map();
    boolean b = run();
    t->unmap();
    t->display()->sync();
    delete t;
    return b;
}

boolean Dialog::post_at_aligned(
    Coord x, Coord y, float x_align, float y_align
) {
    TransientWindow* t = new TransientWindow(this);
    t->style(new Style(style()));
    t->wm_delete(new DialogHandler(this));
    t->place(x, y);
    t->align(x_align, y_align);
    t->map();
    boolean b = run();
    t->unmap();
    t->display()->sync();
    delete t;
    return b;
}

boolean Dialog::run() {
    Session* s = Session::instance();
    Event e;
    done_ = false;
    for (;;) {
	s->read(e);
	if (e.grabber() != nil || inside(e)) {
	    e.handle();
	} else if (e.type() == Event::key) {
	    keystroke(e);
	}
	if (done_) {
	    break;
	}
	if (s->done()) {
	    accepted_ = false;
	    break;
	}
    }
    return accepted_;
}

void Dialog::dismiss(boolean accept) {
    accepted_ = accept;
    done_ = true;
}
