package net.kldp.logviewer;

import net.kldp.logviewer.common.log.LogViews;
import net.kldp.logviewer.define.LogDefine;
import net.kldp.logviewer.model.GetLogDBInfo;
import net.kldp.logviewer.model.LogViewerEntry;
import net.kldp.logviewer.work.WorkerFileTail;
import net.kldp.logviewer.work.WorkerHttpTail;
import net.kldp.logviewer.work.WorkerTelnetTail;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
/**
 * 메인 출력화면을 정의한다.
 * 
 * @author hangumkj
 *
 */
public class View extends ViewPart {
	private static final Logger logger = LogViews.getLogger(View.class);

	public static final String ID = "net.kldp.logviewer.view";
	Shell viewShell = null;
	private LogViewerEntry viewEntry = null;
	private Color colAlarm = null;
	private String[] searchTxt = null;
//	private IViewSite site = null;
	
	// Telnet방식일 경우
	private WorkerTelnetTail tail = null;
	
	// 파일방식일 경우
	private WorkerFileTail fileTail = null;
	private StyledText styledText = null;
	
	// http 방식일 경우 
	private WorkerHttpTail httpTail = null;
	private Browser browser = null;	
	
	/**
	 * stop 버튼을 클릭했을 경우 잠시 멈춘다.
	 */
	private Action stopAction = new Action("StopView") {		
		public void run() {
			// 파일 방식일 경우
			if(!LogDefine.HTTP_TYPE.equals(viewEntry.getType())) { 
				fileTail.sleep();
			} else {
				httpTail.sleep();
			}
		}
	};
	
	/**
	 * stop 버튼을 클릭했을 경우 잠시 멈춘다.
	 */
	private Action restrartAction = new Action("RestartView") {		
		public void run() {
			// 파일 방식일 경우
			if(!LogDefine.HTTP_TYPE.equals(viewEntry.getType())) { 
				fileTail.reStart();
			} else {
				httpTail.reStart();
			}
		}
	};
	
	public void init(IViewSite site) throws PartInitException {
		super.init(site);
		
		viewShell = site.getShell();
		
		// 화면에 출력하고자 하는 viewer 정보를 가져온다.
		GetLogDBInfo gli = new GetLogDBInfo();
		viewEntry = gli.getLeaf(site.getSecondaryId());
		
		setPartName(viewEntry.getName() + "-" + viewEntry.getRealPath());		
	}
	
	public void createPartControl(Composite parent) {
		if(logger.isDebugEnabled()) { 
			logger.debug("View [type]" + viewEntry.getType() + "[name]" + viewEntry.getName());
		}
		
		Composite top = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		top.setLayout(layout);		
		
		
		// http type이 아닐 경우... 작업한다.
		if(!LogDefine.HTTP_TYPE.equals(viewEntry.getType())) { 
			int intFont = Integer.parseInt(viewEntry.getFont());		
			int intFontSize = Integer.parseInt(viewEntry.getFontSize());
			
			String arryFontCol[] = StringUtils.split(viewEntry.getFontcolor(), '|');				
			Color colFont = new Color(parent.getDisplay(), 
									Integer.parseInt(arryFontCol[0]), 
									Integer.parseInt(arryFontCol[1]), 
									Integer.parseInt(arryFontCol[2])
						);
			
			String arryBackCol[] = StringUtils.split(viewEntry.getBackGroundColor(), '|');				
			Color colBack = new Color(parent.getDisplay(), 
									Integer.parseInt(arryBackCol[0]), 
									Integer.parseInt(arryBackCol[1]), 
									Integer.parseInt(arryBackCol[2])
						);
			
			Font font = new Font(parent.getDisplay(), 
					LogDefine.FONTS[intFont],
					Integer.parseInt(LogDefine.FONT_SIZES[intFontSize]),
					SWT.NORMAL
				);
			
	//		 message contents
			
			String arryAlarmCol[] = StringUtils.split(viewEntry.getAlalrmBackColor(), '|');				
			colAlarm = new Color(parent.getDisplay(), 
									Integer.parseInt(arryAlarmCol[0]), 
									Integer.parseInt(arryAlarmCol[1]), 
									Integer.parseInt(arryAlarmCol[2])
						);			
			
//			logger.debug(arryAlarmCol[0] + arryAlarmCol[1] + arryAlarmCol[2]);
//			logger.debug(viewEntry.getAlalrmData());
			
			// StyledText를 표현하기 위한 코드 시작--------------------
			styledText = new StyledText(top, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);		
			styledText.setFont(font);
			styledText.setForeground(colFont);
			styledText.setBackground(colBack);	    
			styledText.setLayoutData(new GridData(GridData.FILL_BOTH));
			
			// 찾을 낮말을 입력한다.
			searchTxt = StringUtils.split(viewEntry.getAlalrmData(), ",");
			
			styledText.addLineBackgroundListener(new LineBackgroundListener() {
				public void lineGetBackground(LineBackgroundEvent event) {
					if(!"".equals(viewEntry.getAlalrmData())) {
//						logger.debug("called addLineBackgroundListener....");
						
						for(int i=0; i<searchTxt.length; i++) {
					
							// 데이터가 존재하면 back ground 색을 바꾸어준다.
							if(StringUtils.contains(event.lineText, searchTxt[i])) {
								event.lineBackground = colAlarm;
							}	
						}	// end fot
					}
				}	// end method
			});
			
			// 파일을 작업을 시작	
			fileTail = new WorkerFileTail(viewEntry, this);
			fileTail.setPriority(Thread.MIN_PRIORITY);
			fileTail.start();
			
			// 버튼을 추가한다.
			IActionBars actionBars = this.getViewSite().getActionBars(); 
			actionBars.setGlobalActionHandler("StopView", stopAction); //$NON-NLS-1$
			actionBars.setGlobalActionHandler("RestartView", restrartAction); //$NON-NLS-1$
			
		// http type일 경우 작업한다.
		} else {
			GridData gridData = new GridData();
			gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
			gridData.grabExcessVerticalSpace = true;
			gridData.grabExcessHorizontalSpace = true;
			gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
		
			// SWT.V_SCROLL | 
			browser = new Browser(top, SWT.BORDER);
			browser.setLayoutData(gridData);
		
			// 화면 url을 지정한다.
			browser.setUrl(viewEntry.getRealPath());
			
			// 파일을 작업을 시작	
			httpTail = new WorkerHttpTail(viewEntry, this);
			httpTail.setPriority(Thread.MIN_PRIORITY);
			httpTail.start();
			
			IActionBars actionBars = this.getViewSite().getActionBars(); 
			actionBars.setGlobalActionHandler("StopView", stopAction); //$NON-NLS-1$
			actionBars.setGlobalActionHandler("RestartView", restrartAction); //$NON-NLS-1$
		}
	}
	
	public void dispose() {		
		super.dispose();
		
		if(!LogDefine.HTTP_TYPE.equals(viewEntry.getType())) {
			fileTail.shutdown();
		} else {
			httpTail.shutdown();
		}
		
	}
	
	public void setFocus() {
		
		if(!LogDefine.HTTP_TYPE.equals(viewEntry.getType())) { 
			this.styledText.setFocus();
		} else {
			this.browser.setFocus();
		}
	}
	
	/**
	 * File 방식일 때 worker thread에서 데이터를 넘겨받은것을 출력한다.
	 * 
	 * @param msg
	 */
	public void fileAddData(final String msg)   {
		if("".equals(msg)) return;
		
        styledText.getDisplay().syncExec(new Runnable() {
            public void run() {              
                if(styledText.getLineCount() > Integer.parseInt(viewEntry.getLineCount())) styledText.setText("뷰어를 초기화 했습니다.\r\n");
                
                styledText.append(msg);
                styledText.setSelection(styledText.getCharCount());
                
                String alertMsg = "";
                // 알람 데이터가 존재하면 알람을 출력한다.
                if("1".equals(viewEntry.getAlarmType()) && !"".equals(viewEntry.getAlalrmData())) {
					for(int i=0; i<searchTxt.length; i++) {						
						if(StringUtils.contains(msg, searchTxt[i])){ 
							alertMsg += searchTxt[i] + " ";
						}
					}	// end fot
                }
                
                if(!"".equals(alertMsg)) MessageDialog.openError(viewShell, "확인", "[설정하신 메시지] " + alertMsg + "가 발견 되었습니다");
            }	// end run
        });	// end syncExec
	}
	
	/**
	 * http방식일 때 브라우져를 리프레쉬 한다.
	 */
	public void httpRefershData() {
		browser.getDisplay().syncExec(new Runnable() {
			public void run() {                
				browser.refresh();
				
				//  커서를 제일 아래로 위치 시킨다.
//			    ScrollBar sb = browser.getVerticalBar();
//			    if(sb != null) sb.getSelection();
            }	// end run
		});
	}
}
