/**************************************/
	/*	Module to handle screen printing. */
	/**************************************/

#include "fctsys.h"
#include "gr_basic.h"

#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "plot_common.h"

#include "protos.h"

extern void Move_Plume( wxPoint pos, int plume ); // see plot.cpp


/*****************************************************************************
Put out pin number and pin text info, given the pin line coordinates.
The line must be vertical or horizontal.
If PinText == NULL nothing is printed. If PinNum = 0 no number is printed.
Current Zoom factor is taken into account.
If TextInside then the text is been put inside,otherwise all is drawn outside.
Pin Name:	substring beteween '~' is negated
*****************************************************************************/
void LibDrawPin::DrawPinTexts(WinEDA_DrawPanel * panel, wxDC * DC,
				wxPoint & pin_pos, int orient,
				int TextInside, bool DrawPinNum, bool DrawPinName,
				int Color, int DrawMode)
/* DrawMode = GR_OR, XOR ... */
{
int ii, x, y, x1, y1, dx, dy, len;
wxString StringPinNum;
wxString PinText;
int PinTextBarPos[256];
int PinTextBarCount;
int NameColor, NumColor;
int PinTxtLen;
wxSize PinNameSize(m_PinNameSize,m_PinNameSize);
wxSize PinNumSize(m_PinNumSize,m_PinNumSize);
int LineWidth =  g_DrawMinimunLineWidth;

	GRSetDrawMode(DC, DrawMode);

	/* Get the num and name colors */
	NameColor =  Color == - 1 ? ReturnLayerColor(LAYER_PINNAM) : Color;
	NumColor = Color == - 1 ? ReturnLayerColor(LAYER_PINNUM) : Color;

	/* Create the pin num string */
	ReturnPinStringNum(StringPinNum);

	x1 = pin_pos.x; y1 = pin_pos.y;
	switch(orient)
	{
		case PIN_UP: y1 -= m_PinLen; break;
		case PIN_DOWN: y1 += m_PinLen; break;
		case PIN_LEFT: x1 -= m_PinLen; break;
		case PIN_RIGHT: x1 += m_PinLen; break;
	}

	const wxChar * textsrc = m_PinName.GetData();
	float fPinTextPitch = PinNameSize.x * 1.1;
	/* Do we need to invert the string? Is this string has only "~"? */
	PinTextBarCount = 0; PinTxtLen = 0;
	ii = 0;
	while ( * textsrc )
	{
		if ( * textsrc == '~' )
		{
			PinTextBarPos[PinTextBarCount++] = (int)(PinTxtLen * fPinTextPitch);
		}
		else
		{
			PinText.Append(* textsrc);
			PinTxtLen ++;
		}
		
		textsrc++;
	}
	
	PinTxtLen = (int) (fPinTextPitch * PinTxtLen);
	PinTextBarPos[PinTextBarCount] = PinTxtLen;	// Needed if no end '~'
	
	if (PinText[0] == 0) DrawPinName = FALSE;

	if( TextInside )  /* Draw the text inside, but the pin numbers outside. */
	{
		if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
		// It is an horizontal line
		{
			if (PinText && DrawPinName)
			{
				if( orient == PIN_RIGHT)
				{
					x = x1 + TextInside;
					DrawGraphicText(panel, DC, wxPoint(x, y1), NameColor, PinText,
							TEXT_ORIENT_HORIZ,
							PinNameSize,
							GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, LineWidth);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						GRMoveTo(x, y1 - TXTMARGE);
						dy = -PinNameSize.y / 2;
						GRMoveRel(0, dy);
						dx = PinTextBarPos[ii++]; // Get the line pos
						GRMoveRel(dx, 0);
						len = PinTextBarPos[ii++] - dx; // Get the line length
						GRLineRel(&panel->m_ClipBox, DC, len, 0, LineWidth, NameColor);
					}
				}
				else	// Orient == PIN_LEFT
				{
					x = x1 - TextInside;
					DrawGraphicText(panel, DC, wxPoint(x, y1) , NameColor, PinText,
							TEXT_ORIENT_HORIZ,
							PinNameSize,
							GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, LineWidth);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						GRMoveTo(x, y1 - TXTMARGE);
						dy = -PinNameSize.y / 2;
						GRMoveRel(0, dy);
						dx = PinTextBarPos[ii++]; // Get the line pos
						GRMoveRel(dx - PinTxtLen, 0);
						len = PinTextBarPos[ii++] - dx; // Get the line length
						GRLineRel(&panel->m_ClipBox, DC, len, 0, LineWidth, NameColor);
					}
				}
			}

			if ( DrawPinNum)
			{
				DrawGraphicText(panel, DC,
						wxPoint((x1 + pin_pos.x) / 2, y1 - TXTMARGE), NumColor, StringPinNum,
						TEXT_ORIENT_HORIZ, PinNumSize,
						GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM, LineWidth);
			}
		}

		else		 /* Its a vertical line. */
		{	// Text is drawn from bottom to top (i.e. to negative value for Y axis)
			if (PinText && DrawPinName)
			{
				if ( orient == PIN_DOWN )
				{
					y = y1 + TextInside;

					DrawGraphicText(panel, DC, wxPoint(x1, y), NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, LineWidth);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						GRMoveTo(x1 - TXTMARGE, y);
						dy = -PinNameSize.y / 2;
						GRMoveRel(dy , 0);
						dx = PinTextBarPos[ii++]; // Get the line pos
						GRMoveRel(0, PinTxtLen - dx);
						len = PinTextBarPos[ii++] - dx; // Get the line length
						GRLineRel(&panel->m_ClipBox, DC, 0, -len, LineWidth, NameColor);
					}
				}

				else	/* PIN_UP */
				{
					y = y1 - TextInside;

					DrawGraphicText(panel, DC, wxPoint(x1, y), NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM, LineWidth);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						GRMoveTo(x1 - TXTMARGE, y);
						dy = -PinNameSize.y / 2;
						GRMoveRel(dy, 0);
						dx = PinTextBarPos[ii++]; // Get the line pos
						GRMoveRel(0, - dx);
						len = PinTextBarPos[ii++] - dx; // Get the line length
						GRLineRel(&panel->m_ClipBox, DC, 0, -len, LineWidth, NameColor);
					}
				}
			}

			if(DrawPinNum)
			{
				DrawGraphicText(panel, DC,
						wxPoint(x1  - TXTMARGE, (y1 + pin_pos.y) / 2) , NumColor, StringPinNum,
						TEXT_ORIENT_VERT, PinNumSize,
						GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, LineWidth);
			}
		}
	}
	
	else	 /**** Draw num & text pin outside  ****/
	{
		if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
		/* Its an horizontal line. */
		{
			if (PinText && DrawPinName)
			{
               x = (x1 + pin_pos.x) / 2;
				DrawGraphicText(panel, DC, wxPoint(x , y1 - TXTMARGE),
							NameColor, PinText,
							TEXT_ORIENT_HORIZ, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM, LineWidth);

				for ( ii = 0; ii < PinTextBarCount; )
				{
					GRMoveTo(x, y1 - TXTMARGE*2);
					GRMoveRel(-PinTxtLen / 2, -PinNameSize.y );
					dx = PinTextBarPos[ii++]; // Get the line pos
					GRMoveRel(dx, 0);
					len = PinTextBarPos[ii++] - dx; // Get the line length
					GRLineRel(&panel->m_ClipBox, DC, len, 0, LineWidth, NameColor);
				}
			}
			if(DrawPinNum)
			{
				x = (x1 + pin_pos.x) / 2;
				DrawGraphicText(panel, DC, wxPoint(x, y1 + TXTMARGE),
							NumColor, StringPinNum,
							TEXT_ORIENT_HORIZ, PinNumSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, LineWidth);
			}
		}
		else	 /* Its a vertical line. */
		{
			if (PinText && DrawPinName)
			{
               y = (y1 + pin_pos.y) / 2;
				DrawGraphicText(panel, DC, wxPoint(x1 - TXTMARGE , y ),
							NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, LineWidth);

				for ( ii = 0; ii < PinTextBarCount; )
				{
					GRMoveTo(x1 - (TXTMARGE * 2), y);
					GRMoveRel(-PinNameSize.y, -PinTxtLen / 2);
					dx = PinTextBarPos[ii++]; // Get the line pos
					GRMoveRel(0, PinTxtLen - dx);
					len = PinTextBarPos[ii++] - dx; // Get the line length
					GRLineRel(&panel->m_ClipBox, DC, 0, - len, LineWidth, NameColor);
				}
			}

			if(DrawPinNum)
			{
				DrawGraphicText(panel, DC, wxPoint(x1 + TXTMARGE , (y1 + pin_pos.y) / 2),
							NumColor, StringPinNum,
							TEXT_ORIENT_VERT, PinNumSize,
							GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, LineWidth);
			}
		}
	}
}

/*****************************************************************************
* Plot pin number and pin text info, given the pin line coordinates.	  *
* Same as DrawPinTexts((), but output is the plotter
* The line must be vertical or horizontal.						  *
* If PinNext == NULL nothing is printed.									*
* Current Zoom factor is taken into account.					 *
* If TextInside then the text is been put inside (moving from x1, y1 in		 *
* the opposite direction to x2,y2), otherwise all is drawn outside.		 *
*****************************************************************************/
void LibDrawPin::PlotPinTexts(wxPoint & pin_pos, int orient,
				int TextInside, bool DrawPinNum, bool DrawPinName)
{
int dx, len, start;
int ii , x, y, x1, y1, cte;
wxString StringPinNum;
wxString PinText;
int PinTextBarPos[256];
int PinTextBarCount;
int NameColor, NumColor;
int PinTxtLen = 0;
wxSize PinNameSize = wxSize(m_PinNameSize,m_PinNameSize);
wxSize PinNumSize = wxSize(m_PinNumSize,m_PinNumSize);
bool plot_color = (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt;
	
	/* Get the num and name colors */
	NameColor = plot_color ? ReturnLayerColor(LAYER_PINNAM) : -1;
	NumColor = plot_color ? ReturnLayerColor(LAYER_PINNUM) : -1;

	/* Create the pin num string */
	ReturnPinStringNum(StringPinNum);
	x1 = pin_pos.x; y1 = pin_pos.y;
	switch(orient)
	{
		case PIN_UP: y1 -= m_PinLen; break;
		case PIN_DOWN: y1 += m_PinLen; break;
		case PIN_LEFT: x1 -= m_PinLen; break;
		case PIN_RIGHT: x1 += m_PinLen; break;
	}

	const wxChar * textsrc = m_PinName.GetData();
	float fPinTextPitch = PinNameSize.x * 1.1;
	/* Do we need to invert the string? Is this string has only "~"? */
	PinTextBarCount = 0; PinTxtLen = 0;
	ii = 0;
	while ( * textsrc )
	{
		if ( * textsrc == '~' )
		{
			PinTextBarPos[PinTextBarCount++] = (int) (fPinTextPitch * PinTxtLen);
		}
		else
		{
			PinText.Append(* textsrc);
			PinTxtLen ++;
		}
		
		textsrc++;
	}
	
	PinTxtLen = (int) (fPinTextPitch * PinTxtLen);
	PinTextBarPos[PinTextBarCount] = PinTxtLen;	// Needed if no end '~'
	
	if (PinText[0] == 0) DrawPinName = FALSE;

	if (TextInside)  /* Draw the text inside, but the pin numbers outside. */
	{
		if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
		{	  /* Its an horizontal line. */
			if (PinText && DrawPinName)
			{
				if( orient == PIN_RIGHT)
				{
					x = x1 + TextInside;
					PlotGraphicText(g_PlotFormat, wxPoint(x, y1), NameColor, PinText,
							TEXT_ORIENT_HORIZ,
							PinNameSize,
							GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						cte = y1 - PinNameSize.y/2 - TXTMARGE;
						dx = PinTextBarPos[ii++]; // Get the line pos
						Move_Plume( wxPoint(x+dx, cte), 'U');
						len = PinTextBarPos[ii++]; // Get the line end
						Move_Plume( wxPoint(x + len, cte), 'D');
					}
				}
				else	// orient == PIN_LEFT
				{
					x = x1 - TextInside;
					PlotGraphicText(g_PlotFormat, wxPoint(x, y1),
							NameColor, PinText, TEXT_ORIENT_HORIZ,
							PinNameSize,
							GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						cte = y1 - PinNameSize.y/2 - TXTMARGE;
						dx = PinTextBarPos[ii++]; // Get the line pos
						Move_Plume( wxPoint(x+dx - PinTxtLen, cte), 'U');
						len = PinTextBarPos[ii++]; // Get the line end
						Move_Plume(wxPoint(x + len - PinTxtLen, cte), 'D');
					}
				}
			}

			if (DrawPinNum)
			{
				PlotGraphicText( g_PlotFormat, wxPoint((x1 + pin_pos.x) / 2, y1 - TXTMARGE),
						NumColor, StringPinNum,
						TEXT_ORIENT_HORIZ, PinNumSize,
						GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM);
			}
		}

		else		 /* Its a vertical line. */
		{
			if (PinText && DrawPinName)
			{
				if ( orient == PIN_DOWN )
				{
					y = y1 + TextInside;

					PlotGraphicText( g_PlotFormat, wxPoint(x1, y), NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						cte = x1 - PinNameSize.y/2 - TXTMARGE;
						dx = PinTextBarPos[ii++]; // Get the line pos
						Move_Plume( wxPoint(cte, y + PinTxtLen - dx), 'U');
						len = PinTextBarPos[ii++]; // Get the line end
						Move_Plume( wxPoint(cte , y + PinTxtLen - len), 'D');
					}
				}

				else	/* PIN_UP */
				{
					y = y1 - TextInside;

					PlotGraphicText( g_PlotFormat, wxPoint(x1, y), NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM);

					for ( ii = 0; ii < PinTextBarCount; )
					{
						cte = x1 - PinNameSize.y/2 - TXTMARGE;
						dx = PinTextBarPos[ii++]; // Get the line pos
						Move_Plume( wxPoint(cte, y -dx), 'U');
						len = PinTextBarPos[ii++]; // Get the line end
						Move_Plume(wxPoint(cte, y - len), 'D');
					}
				}
			}

			if (DrawPinNum)
			{
				PlotGraphicText( g_PlotFormat, wxPoint(x1 - TXTMARGE, (y1 + pin_pos.y) / 2),
							NumColor, StringPinNum,
							TEXT_ORIENT_VERT, PinNumSize,
							GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER);
			}
		}
	}
	
	else	 /* Draw num & text pin outside */
	{
		if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
		/* Its an horizontal line. */
		{
			if (PinText && DrawPinName)
			{
				x = (x1 + pin_pos.x) / 2;
				PlotGraphicText( g_PlotFormat, wxPoint(x, y1 - TXTMARGE),
							NameColor, PinText,
							TEXT_ORIENT_HORIZ, PinNameSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_BOTTOM);

				for ( ii = 0; ii < PinTextBarCount; )
				{
					cte = y1 - PinNameSize.y - TXTMARGE*2;
					start = x - (PinTxtLen / 2);
					dx = PinTextBarPos[ii++]; // Get the line pos
					Move_Plume( wxPoint(start + dx, cte), 'U');
					len = PinTextBarPos[ii++]; // Get the line end
					Move_Plume(wxPoint(start + len, cte), 'D');
				}
			}
			if (DrawPinNum)
			{
				x = (x1 + pin_pos.x) / 2;
				PlotGraphicText(g_PlotFormat, wxPoint(x, y1 + TXTMARGE),
							NumColor, StringPinNum,
							TEXT_ORIENT_HORIZ, PinNumSize,
							GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP);
			}
		}
		else	 /* Its a vertical line. */
		{
			if (PinText && DrawPinName)
			{
				y = (y1 + pin_pos.y)  / 2;
				PlotGraphicText( g_PlotFormat, wxPoint(x1 - TXTMARGE,y),
							NameColor, PinText,
							TEXT_ORIENT_VERT, PinNameSize,
							GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER);

				for ( ii = 0; ii < PinTextBarCount; )
				{
					cte = x1 - PinNameSize.y - TXTMARGE*2;
					start = y + (PinTxtLen / 2);
					dx = PinTextBarPos[ii++]; // Get the line pos
					Move_Plume( wxPoint(cte, start - dx), 'U');
					len = PinTextBarPos[ii++]; // Get the line end
					Move_Plume( wxPoint(cte, start - len), 'D');
				}
			}

			 if (DrawPinNum)
			{
				PlotGraphicText( g_PlotFormat, wxPoint(x1 + TXTMARGE, (y1 + pin_pos.y) / 2),
							NumColor, StringPinNum,
							TEXT_ORIENT_VERT, PinNumSize,
							GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER);
			}
		}
	}
}