

function MiniView(id, options) {
    this.options = options || {};
    this.options._default = function(key, value) {
	if (this[key] == null) {
	    this[key] = value;
	}
    };
    this.options._default('loadingHTML', '<div class="message">loading...</div>');
    this.options._default('width', 330);
    this.options._default('height', 290);
    this.options._default('backgroundImage', 'miniview_bg.png');
    this.options._default('backgroundColor', '#fff');
    this.options._default('hasClose', true);
    this.options._default('closeSrc', 'close.gif');
    this.options._default('closeHeight', 16);
    this.options._default('closeWidth', 16);
    this.options._default('closePad', 0);
    this.options._default('baseZIndex', 1000);

    this.totalWidth = parseInt(this.options.width);
    this.totalHeight = parseInt(this.options.height);
    this.edgeOffsetX = 10;
    this.edgeOffsetY = 10;

    this.wrap = new Element('div', { 'id': id, 'class': 'mini_view' });
    this.wrap.hide();
    this._absolutize(this.wrap);
    this._setSize(this.wrap, this.totalWidth, this.totalHeight);
    this._setOffset(this.wrap, 0, 0, this.options.baseZIndex + 1);
    document.body.appendChild(this.wrap);

    this.bg = null;
    if (this.options.backgroundImage) {
	this.bg = new Element('img', { 'src': this.options.backgroundImage });
	this._absolutize(this.bg);
	this._setSize(this.bg, this.totalWidth, this.totalHeight);
	this._setOffset(this.bg, 0, 0, 9);
	this.wrap.appendChild(this.bg);
    }

    this.header = null;
    this.headerHeight = 0;
    this.closeButton = null;
    if (this.options.hasClose) {
	this.headerHeight = this.options.closeHeight + 2*this.options.closePad;
	this.header = new Element('div');
	this._absolutize(this.header);
	this._setSize(this.header, this.totalWidth - 2*this.edgeOffsetX, this.headerHeight);
	this._setOffset(this.header, this.edgeOffsetX, this.edgeOffsetY, 10);
	this.header.setStyle({ backgroundColor: this.options.backgroundColor });
	this.wrap.appendChild(this.header);

	this.closeButton = new Element('img', { 'src': this.options.closeSrc });
	this._absolutize(this.closeButton);
	this.closeButton.setStyle({ width: this.options.closeWidth + 'px', height: this.options.closeHeight + 'px', top: this.options.closePad + 'px', right: this.options.closePad + 'px', cursor: 'pointer' });
	this.header.appendChild(this.closeButton);
	var view = this;
	this.closeButton.observe('click', function(event) { 
	    view.hide();
	    event.stop();
	});
    }

    this.content = new Element('div', { 'id': id + '_content', 'class': 'mini_view_content' });
    this._absolutize(this.content);
    this._setSize(this.content, this.totalWidth - 2*this.edgeOffsetX, this.totalHeight - 2*this.edgeOffsetY - this.headerHeight);
    this._setOffset(this.content, this.edgeOffsetX, this.edgeOffsetY + this.headerHeight, 10);
    this.content.setStyle({ overflow: 'auto', backgroundColor: this.options.backgroundColor });
    this.content.update(this.options.loadingHTML);
    this.wrap.appendChild(this.content);

    this.back = new Element('div');
    this.back.hide();
    this._absolutize(this.back);
    this._setSize(this.back, 0, 0);
    this._setOffset(this.back, 0, 0, this.options.baseZIndex);
    document.body.appendChild(this.back);
    var view = this;
    this.back.observe('click', function(event) { 
	view.hide();
	event.stop();
    });
}

MiniView.prototype._setSize = function(el, w, h) {
    el.setStyle({ width: w + 'px', height: h + 'px' });
    return el;
}

MiniView.prototype._setOffset = function(el, x, y, z) {
    var o = { left: x + 'px', top: y + 'px' };
    if (z) {
	o.zIndex = '' + z;
    }
    el.setStyle(o);
    return el;
}

MiniView.prototype._absolutize = function(el) { // IE7 doesn't like prototype.js's absolutize().
    el.setStyle({ position: 'absolute' });
    return el;
}

MiniView.prototype._max = function(a, b) {
    if (a >= b) {
	return a;
    }
    return b;
}

MiniView.prototype.setContentLayout = function(html, updateID) {
    this.content.update(html);
    this.layoutUpdateID = updateID;
}

MiniView.prototype.load = function(url, params, loadingHTML, onSuccessCB) {
    this.setContent(loadingHTML || this.options.loadingHTML);

    var o = this;
    var options = {};
    options.method = 'get';
    options.onSuccess = function(response) {
	o.setContent(response.responseText);
	if (onSuccessCB)
	    (onSuccessCB)(o);
    };
    options.onFailure = function(response) {
	o.setContent('<div class="message">(Error loading content: ' + response.statusText + ')</div>');
    };
    options.onException = function(xhr, ex) {
	o.setContent('<div class="message">(Error loading content: ' + ex.message + ')</div>');
    };
    if (params) {
	options.parameters = params;
    }
    this.request = new Ajax.Request(url, options);
}

MiniView.prototype.setContent = function(html) {
    if (this.layoutUpdateID && $(this.layoutUpdateID)) {
	$(this.layoutUpdateID).update(html);
    }
    else {
	this.content.update(html);
    }
}

MiniView.prototype.showCentered = function(offX, offY) {
    offX = offX || 0
    offY = offY || 0
    this.show(Math.floor(document.viewport.getWidth() / 2) + offX, Math.floor(document.viewport.getHeight() / 2) + offY);
}

MiniView.prototype.show = function(x, y) {
    var scroll = document.viewport.getScrollOffsets()
    x += scroll.left - Math.floor(this.totalWidth / 2);
    y += scroll.top - Math.floor(this.totalHeight / 2);
    if (x < 10)
	x = 10;
    if (y < 10)
	y = 10;
    this._setOffset(this.wrap, x, y);
    this.wrap.show();

    this._setSize(this.back, this._max($(document.body).getWidth(), document.viewport.getWidth()), this._max($(document.body).getHeight(), document.viewport.getHeight()));
    this._setOffset(this.back, 0, 0);
    this.back.show();
}

MiniView.prototype.sizeToContent = function(cw, ch) {
    cw += 2*this.edgeOffsetX;
    ch += 2*this.edgeOffsetY + this.headerHeight;

    this.totalWidth = cw;
    this.totalHeight = ch;
    this._setSize(this.wrap, this.totalWidth, this.totalHeight);
    this._setSize(this.bg, this.totalWidth, this.totalHeight);
    if (this.options.hasClose) 
	this._setSize(this.header, this.totalWidth - 2*this.edgeOffsetX, this.headerHeight);
    this._setSize(this.content, this.totalWidth - 2*this.edgeOffsetX, this.totalHeight - 2*this.edgeOffsetY - this.headerHeight);
}

MiniView.prototype.hide = function() {
    this.wrap.hide();
    this.back.hide();
}

MiniView.prototype.isHidden = function() {
    return !this.wrap.visible();
}

