/**
 * \file math_phantominset.C
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Georg Baum
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "math_phantominset.h"
#include "math_mathmlstream.h"
#include "math_streamstr.h"

#include "LColor.h"

#include "frontends/Painter.h"

#include "support/std_ostream.h"


MathPhantomInset::MathPhantomInset(Kind k)
	: MathNestInset(1), kind_(k)
{}


std::auto_ptr<InsetBase> MathPhantomInset::doClone() const
{
	return std::auto_ptr<InsetBase>(new MathPhantomInset(*this));
}


void MathPhantomInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
	cell(0).metrics(mi, dim);
	metricsMarkers(dim);
	dim_ = dim;
}


void MathPhantomInset::draw(PainterInfo & pi, int x, int y) const
{
	static int const arrow_size = 4;

	// We first draw the text and then an arrow
	LColor_color const origcol = pi.base.font.color();
	pi.base.font.setColor(LColor::special);
	cell(0).draw(pi, x + 1, y);
	pi.base.font.setColor(origcol);

	if (kind_ == phantom || kind_ == vphantom) {
		// y1---------
		//           / \.
		// y2-----  / | \.
		//            |
		//            |
		// y3-----  \ | /
		//           \ /
		// y4---------
		//          | | |
		//         /  |  \.
		//        x1  x2 x3

		int const x2 = x + dim_.wid / 2;
		int const x1 = x2 - arrow_size;
		int const x3 = x2 + arrow_size;

		int const y1 = y - dim_.asc;
		int const y2 = y1 + arrow_size;
		int const y4 = y + dim_.des;
		int const y3 = y4 - arrow_size;

		// top arrow
		pi.pain.line(x2, y1, x1, y2, LColor::added_space);
		pi.pain.line(x2, y1, x3, y2, LColor::added_space);

		// bottom arrow
		pi.pain.line(x2, y4, x1, y3, LColor::added_space);
		pi.pain.line(x2, y4, x3, y3, LColor::added_space);

		// joining line
		pi.pain.line(x2, y1, x2, y4, LColor::added_space);
	}

	if (kind_ == phantom || kind_ == hphantom) {
		// y1----   /          \.
		//        /              \.
		// y2--- <---------------->
		//        \              /
		// y3----   \          /
		//       |   |        |   |
		//      x1  x2       x3  x4

		int const x1 = x;
		int const x2 = x + arrow_size;
		int const x4 = x + dim_.wid;
		int const x3 = x4 - arrow_size;

		int const y2 = y + (dim_.des - dim_.asc) / 2;
		int const y1 = y2 - arrow_size;
		int const y3 = y2 + arrow_size;

		// left arrow
		pi.pain.line(x1, y2, x2, y3, LColor::added_space);
		pi.pain.line(x1, y2, x2, y1, LColor::added_space);

		// right arrow
		pi.pain.line(x4, y2, x3, y3, LColor::added_space);
		pi.pain.line(x4, y2, x3, y1, LColor::added_space);

		// joining line
		pi.pain.line(x1, y2, x4, y2, LColor::added_space);
	}

	drawMarkers(pi, x, y);
}


void MathPhantomInset::write(WriteStream & os) const
{
	switch (kind_) {
	case phantom:
		os << "\\phantom{";
		break;
	case vphantom:
		os << "\\vphantom{";
		break;
	case hphantom:
		os << "\\hphantom{";
		break;
	}
	os << cell(0) << '}';
}


void MathPhantomInset::normalize(NormalStream & os) const
{
	switch (kind_) {
	case phantom:
		os << "[phantom ";
		break;
	case vphantom:
		os << "[vphantom ";
		break;
	case hphantom:
		os << "[hphantom ";
		break;
	}
	os << cell(0) << ']';
}


void MathPhantomInset::infoize(std::ostream & os) const
{
	switch (kind_) {
	case phantom:
		os << "Phantom";
		break;
	case vphantom:
		os << "Vphantom";
		break;
	case hphantom:
		os << "Hphantom";
		break;
	}
}
