// infobar.C
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegård, 1997-1999

// 13,245,200
#include <stdio.h>
#include <sys/types.h>
#include <time.h>

#include "infobar.h"
#include "proc.h"
#include "qps.h"
#include "misc.h"
#include <QBitmap>

extern 	ControlBar 	*controlbar;
extern	TFrame 		*infobox;  // testing
extern	Qps 		*qps;  // testing


int history_start_idx=0;	// testing

float cpu_total=0;
float cpu_idle=0;
float cpu_used=0;

QMenu *m_popup ;
subcpuRack	*cpubar=0; //DEL extra CPU_window 

// ============================ 
gwidget *x_cpu;
gwidget *x_mem;
gwidget *x_swap;
gwidget *x_utime;
gwidget *x_load_avg;

class VCursor{
	public :
	int px;
	int py;
	int idx;
	bool enable;
};
VCursor vcursor;

void Infobar::hideEvent( QHideEvent * event ) 
{
	//printf("Infobar::hideEvent()\n");
	//cpubar->hide();
}

// return true if the swap meter is redlined
bool Infobar::swaplim_exceeded()
{
	/*
	if(Qps::swaplim_percent) {
		if(procview->swap_total > 0) {
			int free_p = 100 * procview->swap_free / procview->swap_total;
			return free_p < Qps::swaplimit;
		} else
			return FALSE;
	} else {
		return procview->swap_free < Qps::swaplimit;
	} */
}

char rotate_str[]="|/-\\|/-\\";
int rotate_idx=0;
char rotate_char='|';

// who call ?
void Infobar::refresh()
{
	QString s;   

	if(rotate_str[++rotate_idx]==0)	rotate_idx=0;
	rotate_char=rotate_str[rotate_idx];

	
	if(Qps::show_load_graph) 
		update();
		
}

// public : 
//  called by  Qps::refresh()
void Infobar::update_load()
{	
	// Add current load (the 1 min average) as a data point

	//add_history_point((unsigned)(Procinfo::loadavg[0] * history_scale));// //Nomore!!
	//add_history_point2(cpu_used);
	
	//if (procview->dt_total != 0) 	add_history_point((unsigned)(procview->dt_user* history_scale/procview->dt_total));
	
	// NEED SOLUTION!!!!!!!! draw graph before exposed
  	if(isVisible())
		drawGraphOnPixmap();

	// MouseCurosrCheck
}

void Infobar::drawGraphOnPixmap()
{
//	if(isVisible()==false) return;
	if(size()!=pixmap.size())
	{
		///printf("icon_pm changed!!\n");
		pixmap=QPixmap(size()); //resize(w, h);
		pixmap.setMask(QBitmap());	// clear the mask for drawing
	} 

	QPainter p(&pixmap);
	p.fillRect(rect(),QBrush(Qt::black));	//p.fill(Qt::black);
	
	for(int i=0;i<wlist.size();i++)
		wlist[i]->draw(&p);
	
	make_graph(width(), height(),&p);
}

// if p, then show A and hide B; otherwise do the opposite
void Infobar::showup()
{
	//if(cpubar->isVisible())	cpubar->raise();
}

//DEL?
void Infobar::show_and_hide(bool p, QWidget *a, QWidget *b)
{
	if(!p) {
		QWidget *c = a;
		a = b;
		b = c;
	}
	if(!a->isVisible()) {
		b->hide();
		a->show();
	}
}



#define TOTAL_BAR 50
QColor total_color;
QColor part1_color;
QColor part2_color;
QColor part3_color;
// DRAFT CODE : DRAFT CODE !!
// return width
int drawSPECTRUM(QPainter *p,int x,int y,char *name,
		int total, int part1,int part2=0,int part3=0,int h=0) 
{
	int total_width;
	//bluelay  0,180,255 
	//Move to Infor::Inforbar()
	total_color.setRgb(0,65,55);
	part1_color.setRgb(0,255,210);
	part2_color.setRgb(0,185,150);
	part3_color.setRgb(0,160,120);

	int i,w;
	int tx,ty,bar_xoffset,bar_h;
	int bar;
	
	char buff[32]="NO";
	
	if(total==0){
		name=strcat(buff,name);
	}
	
	if(h==0)  h=pf_char_height();
	
	w=2+pf_write(p,x+2,y+2,name)+3;
	bar_xoffset= x + w ;

	if(total==0) 
		return w; //**

	// draw total_dark_null line
	bar_h=h-1;
	ty=y+2;
	tx=0;
	p->setPen(total_color);
	for(i=0; i < TOTAL_BAR; i++)	
	{	
		p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
		tx++;
		tx++;
	}
	total_width = w+ tx;

	if (total==0) total=1;
	tx=0;
	// draw part1 
	p->setPen(part1_color);
	bar=part1*TOTAL_BAR/total;
	if(bar==0 and part1!=0 ) bar=1;
	for(i=0; i < bar ; i++ )
	{	
		p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
		tx+=2;
		//tx++;
	}

	if( part2 >= 0 )
	{
		p->setPen(part2_color);
		bar=part2*TOTAL_BAR/total;
		if(bar==0 and part2!=0 ) bar=1;
		for(i=0; i < bar ; i++ )
		{	
			p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
			tx+=2;
			//tx++;
		}
	}
	if( part3 >= 0 )
	{
		p->setPen(part3_color);
		bar=part3*(TOTAL_BAR)/total;
		for(i=0; i < bar ; i++ )
		{	
			p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
			tx+=2;
		}
	}
	// this occured by reporter. 
	// if(tx>TOTAL_BAR*2 ) printf("Error: %s total =%d, part1=%d, part2=%d part3=%d\n",name,total,part1,part2,part3);
	return total_width;
}

int drawSPECTRUM2(QPainter *p,int x,int y,char *name,
		int total, int part1,int part2=0,int part3=0,int bar_h=9,int bar_w=50) 
{
	// Notice: 
	// 		total=1, part1=1 occurs 	
	
	int total_width;
	//bluelay  0,180,255 
	//Move to Infor::Inforbar()
	total_color.setRgb(0,67,75); //dark
	part1_color.setRgb(0,255,210);
	part2_color.setRgb(0,220,175);
	part3_color.setRgb(0,180,150);

	int i,w;
	int tx,ty,bar_xoffset;
	int bar;
	
	char buff[32]="NO";
	
	if(total==0){
		//printf("total=0\n") ; //occur
		name=strcat(buff,name);
	}
	
	
	w=2+pf_write(p,x+2,y+2,name)+2;
	bar_xoffset= x + w ;

	if(total==0) 
		return w; //**

	// draw total_dark_null line
	bar_h=bar_h-1;	// if(h==0)  h=pf_char_height(); //9

	ty=y+2;
	tx=0;
	p->setPen(total_color);
	for(i=0; i < bar_w ; i++)	
	{	
		p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
		tx+=2;
	}
	total_width = w+ tx;

	if (total==0)  total=1; // safer divide error.
	
	tx=0;
	// draw part1 
	p->setPen(part1_color);
	bar=part1*bar_w/total;
	if(bar==0 and part1!=0 ) bar=1;
	for(i=0; i < bar ; i++ )
	{	
		p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
		tx+=2;
		//tx++;
	}

	if( part2 >= 0 )
	{
		p->setPen(part2_color);
		bar=part2*bar_w/total;
		if(bar==0 and part2!=0 ) bar=1;
		for(i=0; i < bar ; i++ )
		{	
			p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
			tx+=2;
			//tx++;
		}
	}
	if( part3 >= 0 )
	{
		p->setPen(part3_color);
		bar=part3*(bar_w)/total;
		for(i=0; i < bar ; i++ )
		{	
			p->drawLine(bar_xoffset+tx,ty,bar_xoffset+tx,ty+bar_h);
			tx+=2;
		}
	}
	// this occured by reporter. 
	 if(tx>TOTAL_BAR*2 ) { 
		 printf("Error: %s total =%d, part1=%d, part2=%d part3=%d\n",name,total,part1,part2,part3);
		 return -1;}
//	if(part1<0){ printf("total=%d part1=%d part2=%d\n",total,part1,part2);	return -1;}
	//printf("%s total =%d, part1=%d, part2=%d part3=%d\n",name,total,part1,part2,part3);
	return total_width;
}

char 	str_buff[512];
#define TIMEDIFF(kind) procview->cpu_times(cpu_id, Proc::kind) - procview->old_cpu_times(cpu_id, Proc::kind)
class w_cpu: public gwidget
{
	private:
		int cpu_n;
		long total, user, system, idle,nice, wait;

	public:
	virtual void draw(QPainter *p)
	{
		x=0;
		char buff[32];
		int cpu_id;
		int cpu_n;
		int gheight=10;
		int w;
		int mw;

		user=0, system=0, idle=0,nice=0, wait=0;
		
		//if(procview->num_cpus>=4) // temporaly... 
		//else 
        cpu_n=procview->num_cpus;
 
 		width=0;
		
		//if(cpubar->isVisible() and cpu_n>3)  
		if(true)  
		{
			// show Total CPU 
			cpu_id=cpu_n;
			user = TIMEDIFF(CPUTIME_USER);
#ifdef LINUX
			nice = TIMEDIFF(CPUTIME_NICE);
#endif
			system = TIMEDIFF(CPUTIME_SYSTEM);
#ifdef SOLARIS
			wait = TIMEDIFF(CPUTIME_WAIT);
#endif
			idle = TIMEDIFF(CPUTIME_IDLE);
			total=user+system+wait+nice+idle;
			width=drawSPECTRUM(p,0,0,"CPU",total,user,system,nice,gheight-1);
		//	width+=5;
		}

		for(cpu_id = 0; cpu_id < cpu_n; cpu_id++) {
			
			//	if(procview->num_cpus == procview->old_num_cpus) 
			user = TIMEDIFF(CPUTIME_USER); 
			idle = TIMEDIFF(CPUTIME_IDLE);
			system = TIMEDIFF(CPUTIME_SYSTEM);
#ifdef LINUX
			nice = TIMEDIFF(CPUTIME_NICE);
#endif
#ifdef SOLARIS
			wait = TIMEDIFF(CPUTIME_WAIT);
#endif

		#ifdef LINUX
			total=user+system+nice+idle;
		#endif 
		#ifdef SOLARIS
			total=user+system+wait+idle;
		#endif 

			if(cpu_n>1 and cpu_n<129 ) // 9~16 
			{
				int bar_w=0;
				if(cpu_n<5)
					bar_w=50;
				else if(cpu_n<9) 
					bar_w=23;
				else if(cpu_n<17)
					bar_w=18;
				else bar_w=13;
		
				int r,c;
				c=cpu_id/4;
				r=cpu_id%4;
				sprintf(buff,"%d",cpu_id);
				mw=4*3 +(bar_w*2+8*2 -1)*c;
				if(c>=1) mw-=6;
				if(c>=2) mw-=6;
				
				
				
				if(0 and user<0) 
				{
					printf("cpuid %d , user %d , %d \n", 1,procview->cpu_times(1, Proc::CPUTIME_USER),procview->old_cpu_times(0, Proc::CPUTIME_USER));
				}
				
				#ifdef LINUX
			 	int z=drawSPECTRUM2(p, mw,gheight+ 1 + r*(gheight-1) ,buff,total,user,system,nice,gheight-2,bar_w);
				#endif

				#ifdef SOLARIS
			 	int z=drawSPECTRUM2(p, mw,gheight+ 1 + r*(gheight-1) ,buff,total,user,system,wait,gheight-2,bar_w);
				//drawSPECTRUM(p,0,cpu_id*10,buff,total,user,system,wait);
				#endif
			}
		}
		p->fillRect(0,gheight+2, 50 + mw + 100 ,gheight*4,QColor(0,0,0,130));
		height=gheight * 1;
	}

	virtual char *info()
	{
		char str[80];
		float f_user,f_nice,f_system,f_wait;
	
		f_user=(float)user/total *100;
		f_nice=(float)nice/total *100;
		f_wait=(float)wait/total *100;
		f_system=(float)system/total *100;
#ifdef LINUX
		sprintf(str_buff,"user: %1.1f%%  system:%1.1f%%  nice:%1.1f%% "
			,f_user,f_system,f_nice);
#endif

#ifdef SOLARIS
		sprintf(str_buff,"user: %1.1f%%  system:%1.1f%%  nice:%1.1f%% " ,f_user,f_system,f_wait);
#endif
		return str_buff;
	};

};


class w_mem: public gwidget
{
	private :
		int used;
	public:
	virtual void draw(QPainter *p)
	{
		height=pf_char_height()+4;
		x=x_cpu->xpluswidth()+10;
#ifdef LINUX
		used = procview->mem_total -  procview->mem_free - procview->mem_buffers - procview->mem_cached;
		width=drawSPECTRUM(p,x,0,"MEM",procview->mem_total,used, procview->mem_cached,procview->mem_buffers);
#endif

#ifdef SOLARIS
		used = procview->mem_total -  procview->mem_free;
		width=drawSPECTRUM(p,x,0,"MEM",procview->mem_total,used);
#endif

	}
	virtual char *info()
	{
		char str[80];

		strcpy(str_buff,"Total: ");
		mem_string(procview->mem_total,str);
		strcat(str_buff,str);
	
		strcat(str_buff,"  used: ");
		mem_string(used,str);
		strcat(str_buff,str);

#ifdef LINUX
		strcat(str_buff,"  cached: ");
		mem_string(procview->mem_cached,str);
		strcat(str_buff,str);
		strcat(str_buff,"  buffer: ");
		mem_string(procview->mem_buffers,str);
		strcat(str_buff,str);
#endif

	
	//	sprintf(str_buff,"Total: %dKb , cache: %dKb , buffer: %dKb",
	//		procview->mem_total,procview->mem_cached,procview->mem_buffers);
		return str_buff;
	};

};

class w_swap: public gwidget
{
	private:
		int used;
	public:
	virtual void draw(QPainter *p)
	{	
		x=x_mem->xpluswidth()+10;
		used=procview->swap_total-procview->swap_free;
		width=drawSPECTRUM(p,x,0,"SWAP",procview->swap_total,used);
		height=pf_char_height()+4;
	}
	virtual char *info()
	{	
		char str[80];
		
		strcpy(str_buff,"Total: ");
		mem_string(procview->swap_total,str);
		strcat(str_buff,str);
		strcat(str_buff,"  Free: ");
		mem_string(procview->swap_free,str);
		strcat(str_buff,str);
		strcat(str_buff,"  Used: ");
		mem_string(used,str);
		strcat(str_buff,str);

		//sprintf(str_buff,"Total: %d Kbyte , used %d Kbyte",
		//		procview->swap_total,procview->swap_free);
		return str_buff;
	};
};

// DRAFT CODE  !!
int drawUTIME(QPainter *p,int x,int y,long boot_time)
{
	char buff[1024]; 
	//printf("size of long=%d, size of time_t=%d \n",sizeof(long),sizeof(time_t));
	long u = (long)time(NULL) - (long)boot_time;
	int up_days = u / (3600 * 24);
	u %= (3600 * 24);
	int up_hrs = u / 3600;
	u %= 3600;
	int up_mins = u / 60;
	int sec = u % 60;
	if(up_days == 0) {
		if(up_hrs == 0)
			sprintf(buff,"UPTIME %d:%02d", up_mins,sec);
		else
			sprintf(buff,"UPTIME %d:%02d:%02d", up_hrs, up_mins,sec);
	} else
		sprintf(buff,"UPTIME %dDAY%s,%d:%02d:%02d", up_days, (up_days == 1) ? "" : "s", up_hrs, up_mins,sec);
	return pf_write(p,x,y,buff );
}

class w_utime: public gwidget
{
	public:
	virtual void draw(QPainter *p)
	{
		height=pf_char_height()+4;
		x=x_swap->xpluswidth()+10;
		width=drawUTIME(p,x,2,procview->boot_time);
	}
	virtual char *info()
	{
		return "passed time after system booting";
	};
};

class w_load_avg : public gwidget
{
	virtual void draw(QPainter *p)
	{
		char buff[64];
		//printf("w_load_avg\n");
		//sprintf(buff,"QPS %3.02f%%", Procinfo::loadQps);
		sprintf(buff," 1m:%1.02f 5m:%1.02f 15m:%1.02f",		 
					procview->loadavg[0],procview->loadavg[1], procview->loadavg[2]);

		width=pf_str_width(buff);

		x=parent->width()-width-6;
		
		int w=x_utime->xpluswidth()+15;
		if (x<w)
			x=w;
		
		pf_write(p,x,2,buff);

		//
		x=parent->width()-8;
		y=parent->height()-9;

		char str[2]={0,0};
		str[0]=rotate_char;
		pf_write(p,x,y,str);

	}
	virtual char *info()
	{
		return "Average CPU%% each 1, 5 ,15 minutes";
	};

};

Infobar::Infobar(QWidget *parent,Procview *pv): QFrame(parent)
{
	procview=pv;
	official_height=50;

	//setCursor ( QCursor(Qt::CrossCursor) ) ;
	{
	npoints=0,peak=0,h_index=0, dirty=true; //

	hist_size=1280;
	history=new float[hist_size]; 

	// setBackgroundRole (QPalette::WindowText);
	setAutoFillBackground ( false );	
	setAttribute(Qt::WA_OpaquePaintEvent);
	//setFrameShape(QFrame::Panel);
	setFrameShadow(QFrame::Sunken);
	setMinimumHeight(official_height);
	setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Fixed);
	//setStyleSheet("QFrame { background-color: yellow }");	
	x_cpu=new w_cpu();
	x_cpu->setParent(this,pv);
	x_mem=new w_mem();
	x_mem->setParent(this,pv);
	x_swap=new w_swap();
	x_swap->setParent(this,pv);
	x_utime=new w_utime();
	x_utime->setParent(this,pv);
	x_load_avg=new w_load_avg();	
	x_load_avg->setParent(this,pv);
	
	wlist.append(x_cpu);
	wlist.append(x_mem);
	wlist.append(x_swap);
	wlist.append(x_utime);
	wlist.append(x_load_avg);
	
	QWidget::setMouseTracking(true);
	} // 
	
	int i = 0;
	//is_vertical = Qps::vertical_cpu_bar; //DEL 

//	cpubar=new subcpuRack(parent,pv);	
   	
	m_popup = new QMenu("popup",this);
	QAction *act=new QAction("Under Development",this);
	act->setDisabled(true);
	m_popup->addAction(act);

}

Infobar::~Infobar()
{
	delete[] history;
}

// old style : relative method  
// add value to the history, updating peak.
// USING
void Infobar::add_history_point(unsigned int value)
{	
// simul circular buffer
	history[h_index++] = value; //float 
	if(h_index >= hist_size)
		h_index = 0;
	if(npoints < hist_size)
		npoints++;
}


//BACKUP: add value to the history, updating peak.
void Infobar::add_history_point2(float value)
{
	static float v[3]={0,0,0};
	static float last_val=0;
	
	float f;
	f=last_val-value;
	//if (f > 0)
	//	value+=f/1.15;  // slow up ,slow down
	//else 
		value+=f/1.5;  // slow up ,slow down
	history[h_index++] = value;
	if(h_index >= hist_size)
		h_index = 0;
	if(npoints < hist_size)
		npoints++;
	if(value > peak)
		peak = value;
	else {
		peak = 0;		// no negative values
		for(int i = 0; i < npoints; i++)
			if(history[i] > peak)
				peak = history[i];
	}
	// printf("hist_size=%d h_index=%d  val=%f\n",hist_size,h_index,value);
			
	last_val=value;
}




// return updated pixmap for use as an icon
QPixmap *Infobar::make_icon(int w, int h)
{
	if(w != icon_pm.width() or h != icon_pm.height()) {
		///printf("icon_pm changed!!!!!!!!!!!!!!!!!!11\n");
		icon_pm=QPixmap(w,h); //pm.resize(w, h);
		icon_pm.setMask(QBitmap());	// remove the mask for drawing
	} 
	QPainter pt(&icon_pm);
	pt.fillRect(0,0,w,h,QBrush(Qt::black));

	if(0)
	{
	/*	int thick=h/10;
		int bottom=h/4;

		pt.setClipRect();
		pt.translate(); */
	}

	make_graph(w, h,&pt);
	return &icon_pm;
}

void Infobar::mousePressEvent(QMouseEvent *e)
{
	emit clicked();
	if(e->button()==Qt::LeftButton)
	{
		vcursor.enable=true;
		return;
	}
		
	if(e->button()==Qt::RightButton)
		m_popup->popup(e->globalPos());
}


// TODO: 1.sort 2. time 
QString doHistory(SysHistory *sysh)
{
	QString str;
	Procinfo *p;
	int max=0;
	
	char buf[128];
	//sprintf(buf,"miniHistory /* %.02f%%",sysh->load_cpu*100);
	sprintf(buf,"miniHistory alpha");
	str+=QString::fromAscii(buf);
	foreach(p,sysh->procs)
	{
		if(p->pcpu==0) continue;
		sprintf(buf," (%.02f%%)",p->pcpu);
		str+="\n"+ p->command + QString::fromAscii(buf);
	}
	return str;
}

// only works if mouse cursor in this area 
void Infobar::mouseMoveEvent(QMouseEvent *e)
{
	int x=0,y=0;
	int half_height=height()/2;
	int dy;
	int gap;

	px=e->pos().x() ; // x in Infobar
	py=e->pos().y() ; // y in Infobar

	dy=py-half_height; // 
	dy/=2;
	
	//printf("px=%d py=%d  y=%d h=%d , dy=%d\n",px,py,y,height(),dy);
	//gap=infobox->width() + px  - width();
	
	int i;
	int setinfo=0;
	for(i=0;i<wlist.size();i++)
		if(wlist[i]->intersect(px,py)) 
		{
			setinfo=1;
			infobox->setText(wlist[i]->info());
			break;
		}

	//printf("procview npoints=%d  px=%d\n",npoints,px);
	QString text;
	int idx=px+history_start_idx;
	//if(px<npoints) //h_index, npoints
	if(idx<procview->history.size() and idx >= 0 ) 
	{	
		//	printf("procview idx=%d px=%d\n",idx,px); 
			text+=doHistory(procview->history[idx]);
			
	}
	else 
	{
		text ="";
	}

	if (setinfo==0)	infobox->setText(text);

	QPoint p=mapTo(qps,e->pos()); //??
	
	//infobox->move(a.x()+16,a.y()+4);
	//infobox->setPos(p.x()+16,p.y()+4);
	infobox->setPos();

//	vcursor.px=p.x();
//	update(p.x()-5,0,p.x()+5,height());
}

void Infobar::enterEvent ( QEvent * ) 
{
//	infobox->hide();
}

void Infobar::leaveEvent ( QEvent * ) 
{

	infobox->hide();

	return; 
	/*
	if(controlbar and controlbar->isHidden())
	{
		// controlbar->show();
		setMinimumHeight(official_height);
	} */
}


// DRAFT CODE
// draw the load graph on the internal pixmap, if needed
// called by 
// 		1.make_icon(int w, int h)
// 		2.paintEvent()
// 		3.update_load()
void Infobar::make_graph(int w, int h,QPainter *p )
{
    //QPainter p(this);
	//p.setBackgroundMode (Qt::OpaqueMode);	p.setBackground(QBrush(Qt::black));
	//p->fillRect(0,0,w,h,QBrush(Qt::black));
	//p->fill(Qt::black);
	float ratio=h;
	
	if(h==official_height) // tmp
	{
		ratio=h-11;
	}


	int hsize=procview->history.size();
	int start=hsize-w;

	if(start<0) 
		start=0;

	QPolygon pa(hsize-start);  //QVector pa(npts); 
//	QPolygon point_array_io(hsize-start);  

	int idx=0;
	for(int i = start; i < procview->history.size(); i++,idx++) {
		SysHistory *hist=procview->history[i];
		// printf("[%d] hist =%f\n",i,hist->load_cpu);
		pa[idx] = QPoint(idx, h - 1 - (int)(hist->load_cpu * ratio));
	///	point_array_io[idx] = QPoint(idx, h - 1 - (int)(hist->load_io * ratio));
	}	

	if(h==official_height)
	{	
		history_start_idx=start; // for MousePointer!!
		npoints=idx;  //printf("x npoints=%d \n",npoints);
	}

//	p->setPen(QColor(100,100,250));	//p.setPen(QColor(0,70,54));
//	p->drawPolyline(point_array_io);

	//draw scale lines
	p->setPen(QColor(0,210,100));	//p.setPen(QColor(0,70,54));
	p->drawPolyline(pa);
	

	dirty = FALSE;

}


void Infobar::resizeEvent ( QResizeEvent * e )
{
	//static int first=0; if(first==0){	drawPixmap(); first=1;}
	drawGraphOnPixmap(); 
}

// DRAFT CODE  !!!
void Infobar::paintEvent ( QPaintEvent *e )
{
	//printf("Infobar()\n");
	// Full redraw!
	QRect ur = e->rect();	// update rectangle
    QPainter p(this);
	
	//from update_load()  
	p.drawPixmap(ur,pixmap,ur);
	
	//drww VCursor
	if(vcursor.enable)
	{
		int px=vcursor.px;
	///	p.setPen(QColor(80,195,80));
	///	p.drawLine (px,0,px,height());
	}
}

subcpuRack::subcpuRack(QWidget *p,Procview *pv): QWidget(p)
{
	parent=p;
	procview=pv;
	//setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
	//setWindowFlags(Qt::FramelessWindowHint |Qt::Tool );
	setAttribute(Qt::WA_OpaquePaintEvent);
	QPalette pal;
	pal.setColor(QPalette::Window,QColor(0,0,0));
	setPalette(pal);
	QWidget::setMouseTracking(true);
	setMinimumHeight(12);
}

void subcpuRack::refresh()
{

}

void subcpuRack::mousePressEvent(QMouseEvent *e)
{
	m_popup->popup(e->globalPos());
	//hide();
}


// DRAFT CODE  !!!
void subcpuRack::paintEvent ( QPaintEvent *e )
{

	//static QPaint *p=// QPainter *p=new QPainter(this);
    QPainter p(this);
	char buff[128];
	int w;
	int width;
	int x,y;
	int i;
	//QRect cr = contentsRect();
	//QRect cr = p->viewport();
	QRect cr = p.window(); // rect.

	p.fillRect(rect(),QBrush(Qt::black));

	//p->setPen(lineColor);
	p.setPen(QColor(50,50,50));
	p.drawLine(0,0,QWidget::width(),0);
	//p.fillRect(cr,QBrush(QColor(255,255,255,50)));

	unsigned long	total=0,user=0, system=0, idle=0,nice=0, wait=0;
	//if(procview->num_cpus>=4) // temporaly... 
	//else 
	int cpu_n=procview->num_cpus;
	w=2+pf_write(&p,2,2,"SUB CPU");
	width=w;

}


PDisplay::PDisplay(QWidget *parent) :QWidget(parent)
{
	QVBoxLayout *vlayout = new QVBoxLayout;
	vlayout->setMargin(0);
	vlayout->setSpacing(1);
	setLayout(vlayout);
}

Infobar* PDisplay::addSystem(Procview *pv)
{
	Infobar* bar= new Infobar(this,pv);
	layout()->addWidget(bar);
	pv->read_system(); //	
	
	if(0 and pv->num_cpus>9)	
	{
		QWidget *rack;
		rack=new subcpuRack(this,pv);	
		layout()->addWidget(rack);
	}
	return bar;
}
