package demo.common;

import javax.swing.JPanel;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

import demo.frame.IPCFaceManager;
import demo.module.LoginModule;
import netsdk.callback.SUBSCRIBE_CALLBACK;
import netsdk.lib.CommonFunctions;
import netsdk.lib.DeviceSdk;
import netsdk.lib.ErrorCodeAndConst;
import netsdk.lib.ToolKits;
import netsdk.struct.LPNET_SDK_CLIENTINFO;
import netsdk.struct.NET_DVR_SUBSCRIBE_REPLY;
import netsdk.struct.NET_SDK_IVE_BASE_INFO;
import netsdk.struct.NET_SDK_IVE_PICTURE_INFO;

import javax.swing.JLabel;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.Color;

public class IPCFaceMatchPanel extends JPanel {
	private JButton btnLive;
	private Panel plPreview;
	private static PaintPanel pplSource;
	private static PaintPanel pplSnap;
	private static PaintPanel pplTarget;
	private JButton btnSubscribe;
	private JButton btnShow;
	private boolean subed;
	private boolean displayed;
	private boolean previewed;
	private NativeLong m_hPlayHandle;
	private String subReplyStr;
	public static SUBSCRIBE_CALLBACK AlarmCB;
	private JLabel lblNewLabel;
	private JLabel lblNewLabel_1;
	private JLabel lblNewLabel_2;
	private JLabel lblNewLabel_3;
	private static JLabel lblDetail;
	public IPCFaceMatchPanel() {
		subed = false;
		displayed = false;
		previewed = false;
		m_hPlayHandle = new NativeLong();
		m_hPlayHandle.setValue(0);
		setLayout(null);
		setSize(699, 535);
		
		btnLive = new JButton("开始预览");
		btnLive.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!displayed) {
					LPNET_SDK_CLIENTINFO.ByReference lpClientInfo = new LPNET_SDK_CLIENTINFO.ByReference();
					lpClientInfo.lChannel = 0;
					lpClientInfo.streamType = 0;
					lpClientInfo.hPlayWnd = Native.getComponentPointer(plPreview);
					lpClientInfo.bNoDecode = 0;
					m_hPlayHandle = LoginModule.netsdk.NET_SDK_LivePlay(LoginModule.m_hLoginHandle, lpClientInfo, null, null);
				
				    if(m_hPlayHandle.intValue() < 1) {
				  	    System.err.println("开始实时监视失败，错误码" + ToolKits.getErrorCodePrint());
				    } 
				    else {
				  	    System.out.println("Success to start realplay"); 
				  	    displayed = true;
				  	    btnLive.setText("停止预览");
				    }
				}
				else {
					if(LoginModule.netsdk.NET_SDK_StopLivePlay(m_hPlayHandle)) {
						displayed = false;
				  	    btnLive.setText("开始预览");
				  	    plPreview.repaint();
					}
						
				}
				
			}
		});
		btnLive.setBounds(10, 10, 93, 23);
		add(btnLive);
		
		btnSubscribe = new JButton("订阅");
		btnSubscribe.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int chn = 0;//IPC通道一般为0
				NET_DVR_SUBSCRIBE_REPLY.ByReference sSmartSubscrib = new NET_DVR_SUBSCRIBE_REPLY.ByReference();				
				if(!subed) {
					boolean ret = DeviceSdk.INSTANCE.NET_SDK_SmartSubscrib(LoginModule.m_hLoginHandle, 
							ErrorCodeAndConst.NET_DVR_SMART_VFD_MATCH, chn, sSmartSubscrib);
					if(ret) {
						subed = true;						
						subReplyStr = new String(sSmartSubscrib.serverAddress);
						btnSubscribe.setText("取消订阅");
						System.out.println(subReplyStr);
					}
				}
				else {
					byte[] sb = subReplyStr.getBytes();
					Pointer pNativeData = new Memory(sb.length); 
					pNativeData.write(0, sb, 0, sb.length);		
					IntByReference dwResult = new IntByReference();
					boolean ret = DeviceSdk.INSTANCE.NET_SDK_UnSmartSubscrib(LoginModule.m_hLoginHandle, 
							ErrorCodeAndConst.NET_DVR_SMART_VFD_MATCH, chn, pNativeData, dwResult);
					if(ret) {
						subed = false;
						btnSubscribe.setText("订阅");
						pplSource.setOpaque(true);
						pplSource.repaint();
						pplSnap.setOpaque(true);
						pplSnap.repaint();
						pplTarget.setOpaque(true);
						pplTarget.repaint();
					}
					// 释放内存
					long peer = Pointer.nativeValue(pNativeData);
					Native.free(peer);// 手动释放内存
					Pointer.nativeValue(pNativeData, 0);
				}
			}
		});
		btnSubscribe.setBounds(113, 10, 93, 23);
		add(btnSubscribe);
		
		JButton btnAlbum = new JButton("人脸库操作");
		btnAlbum.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				IPCFaceManager ifm = new IPCFaceManager();
				ifm.setVisible(true);
			}
		});
		btnAlbum.setBounds(216, 10, 93, 23);
		add(btnAlbum);
		
		btnShow = new JButton("显示报警");
		btnShow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!displayed)
					AlarmCB = new AnalyzerDataCB();
				else
					AlarmCB = null;
		        // TODO 设置智能分析事件上报回调
				boolean ret = DeviceSdk.INSTANCE.NET_SDK_SetSubscribCallBack(AlarmCB, null);
				if(ret) {
					if(AlarmCB!= null) {
						displayed = true;
						btnShow.setText("停止显示");
					}
					else {
						displayed = false;
						btnShow.setText("显示报警");
						pplSource.setOpaque(true);
						pplSource.repaint();
						pplSnap.setOpaque(true);
						pplSnap.repaint();
						pplTarget.setOpaque(true);
						pplTarget.repaint();
					}						
				}
			}
		});
		btnShow.setBounds(319, 10, 93, 23);
		add(btnShow);
		
		plPreview = new Panel();
		plPreview.setBackground(Color.GRAY);
		plPreview.setBounds(20, 62, 289, 249);
		add(plPreview);
		
		pplSource = new PaintPanel();
		pplSource.setBounds(329, 62, 256, 249);
		add(pplSource);
		
		pplSnap = new PaintPanel();
		pplSnap.setBounds(20, 339, 256, 184);
		add(pplSnap);
		
		pplTarget = new PaintPanel();
		pplTarget.setBounds(286, 339, 256, 184);
		add(pplTarget);
		
		lblNewLabel = new JLabel("抓拍图");
		lblNewLabel.setBounds(97, 317, 54, 15);
		add(lblNewLabel);
		
		lblNewLabel_1 = new JLabel("目标图");
		lblNewLabel_1.setBounds(379, 317, 54, 15);
		add(lblNewLabel_1);
		
		lblNewLabel_2 = new JLabel("背景图");
		lblNewLabel_2.setBounds(437, 43, 54, 15);
		add(lblNewLabel_2);
		
		lblNewLabel_3 = new JLabel("实时视频");
		lblNewLabel_3.setBounds(123, 41, 54, 15);
		add(lblNewLabel_3);
		
		lblDetail = new JLabel("");
		lblDetail.setBounds(563, 321, 126, 202);
		add(lblDetail);
	}
	
	/**
	 * 写成静态主要是防止被回收
	 */
	private static class AnalyzerDataCB implements SUBSCRIBE_CALLBACK{
		private AnalyzerDataCB() {}
		private static class AnalyzerDataCBHolder {
			private static final AnalyzerDataCB instance = new AnalyzerDataCB();
		}
		public static AnalyzerDataCB getInstance() {
			return AnalyzerDataCBHolder.instance;
		}
		public void invoke(NativeLong lUserID, int dwCommand, Pointer pBuf, int dwBufLen, Pointer pUser) {
			if (dwBufLen == 0 || pBuf == null) {
                return;
            }   
            DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    		DateTime ctime;
    		String folerPath;
    		int restLen = dwBufLen;
    		int offSetLen = 0;
    		int len = 0;
			switch(dwCommand) {
				case ErrorCodeAndConst.NET_SDK_N9000_ALARM_TYPE_FACE_MATCH_FOR_IPC:{
					//pBuf为NET_SDK_IVE_BASE_INFO+NET_SDK_IVE_PICTURE_INFO+图片数据(实时)+NET_SDK_IVE_PICTURE_INFO+图片数据(相册)
			        /*	----------------------
			        |	NET_SDK_IVE_BASE_INFO	|
			        -------------------------
			        |	NET_SDK_IVE_PICTURE_INFO	|
			        -------------------------
			        |	byte[]图片数据(实时)长度：NET_SDK_IVE_PICTURE_INFO.iPicSize		|
			        -------------------------
			        |	NET_SDK_IVE_PICTURE_INFO	|
			        -------------------------
			        |	byte[]图片数据(相册)长度：NET_SDK_IVE_PICTURE_INFO.iPicSize		|
			        -------------------------
			        |	NET_SDK_IVE_PICTURE_INFO	|
			        -------------------------
			        |	byte[]原始背景图片数据(相册)长度：NET_SDK_IVE_PICTURE_INFO.iPicSize		|
			        -------------------------*/
					NET_SDK_IVE_BASE_INFO baseInfo = new  NET_SDK_IVE_BASE_INFO();
					len = baseInfo.size();		 
					CommonFunctions.GetPointerDataToStruct(pBuf, offSetLen, baseInfo);
					baseInfo.read();
					offSetLen += len;//地址偏移
					restLen -= len;//剩余长度
					
					//DateTimeFormatter format1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
					//DateTime ctime1 = DateTime.parse(CommonFunctions.stampToDate(baseInfo.i64SnapTime), format1); 
					//String folerPath1 = CreatePath(lUserID.intValue(), ctime1);
					StringBuilder detail = new StringBuilder("<html>");
					detail.append("time(UTC):");
					detail.append(CommonFunctions.stampToDate(baseInfo.i64SnapTime /1000));
					detail.append("\r\n");
					
					detail.append("name:");
					detail.append(CommonFunctions.ByteToStr(baseInfo.szName, "UTF8"));
					detail.append("\r\n");
					
					detail.append("similarity:");
					detail.append(baseInfo.iSimilarity);
					detail.append("\r\n");
					
					detail.append("temperature:");
					detail.append(baseInfo.temperature/ 100);
					detail.append("\r\n");
					
					detail.append("comparisonRes:");
					detail.append(baseInfo.comparisonRes);
					detail.append("\r\n");
					
					lblDetail.setText(detail.toString());					
										
					NET_SDK_IVE_PICTURE_INFO pictureInfo = new NET_SDK_IVE_PICTURE_INFO();
					len = pictureInfo.size();
					if(restLen < len) {
						break;
					}
					CommonFunctions.GetPointerDataToStruct(pBuf, offSetLen, pictureInfo);
					pictureInfo.read();
					offSetLen += len;//地址偏移
					restLen -= len;//剩余长度
					if(restLen < pictureInfo.iPicSize) {
						break;
					}			 			
					 
					if (pictureInfo.iPicSize > 0) {//实时抓拍图片						
						byte[] data = pBuf.getByteArray(offSetLen, pictureInfo.iPicSize);
		            	ByteArrayInputStream byteArr = new ByteArrayInputStream(data);
		            	try {
		            		BufferedImage bImage = ImageIO.read(byteArr);
							
							pplSnap.setImage(bImage);
							pplSnap.setOpaque(false); 
							pplSnap.repaint();
							
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						
						//byte[] data = pBuf.getByteArray(baseInfo.size() + pictureInfo.size(), pictureInfo.iPicSize);//图片数据(实时抓拍到的)，想办法保存到本地或者显示
						//System.out.println("相似度: " + baseInfo.iSimilarity);
						offSetLen += pictureInfo.iPicSize;//地址偏移
						restLen -= pictureInfo.iPicSize;//剩余长度
					}
					
					
					if(restLen < len) {
						break;
					}
					pictureInfo = new NET_SDK_IVE_PICTURE_INFO();
					CommonFunctions.GetPointerDataToStruct(pBuf, offSetLen, pictureInfo);
					pictureInfo.read();
					offSetLen += len;//地址偏移
					restLen -= len;//剩余长度
					if(restLen < pictureInfo.iPicSize) {
						break;
					}			 						 
					if (pictureInfo.iPicSize > 0) {//相册图片		
						byte[] data = pBuf.getByteArray(offSetLen, pictureInfo.iPicSize);
		            	ByteArrayInputStream byteArr = new ByteArrayInputStream(data);
		            	try {
		            		BufferedImage bImage = ImageIO.read(byteArr);
							
							pplTarget.setImage(bImage);
							pplTarget.setOpaque(false); 
							pplTarget.repaint();
							
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
		            	
						offSetLen += pictureInfo.iPicSize;//地址偏移
						restLen -= pictureInfo.iPicSize;//剩余长度
					}					
					if(restLen < len) {
						break;
					}
					pictureInfo = new NET_SDK_IVE_PICTURE_INFO();
					CommonFunctions.GetPointerDataToStruct(pBuf, offSetLen, pictureInfo);
					pictureInfo.read();
					offSetLen += len;//地址偏移
					restLen -= len;//剩余长度
					if(restLen < pictureInfo.iPicSize) {
						break;
					}			 						 
					if (pictureInfo.iPicSize > 0) {//原始背景图片	
						byte[] data = pBuf.getByteArray(offSetLen, pictureInfo.iPicSize);
		            	ByteArrayInputStream byteArr = new ByteArrayInputStream(data);
		            	try {
		            		BufferedImage bImage = ImageIO.read(byteArr);							
							pplSource.setImage(bImage);
							pplSource.setOpaque(false); 
							pplSource.repaint();							
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}		            	
						offSetLen += pictureInfo.iPicSize;//地址偏移
						restLen -= pictureInfo.iPicSize;//剩余长度
					}					 			
					break;					
				}
			}
		}
	}
	
}
