#include <PeerSDK.h>
using namespace PeerSDK;

#include <stdio.h>

Peer* m_peer = NULL;
PeerStream* m_stream = NULL;

int Finalize(int code)
{
    delete m_peer;

    Peer::Cleanup();
    return code;
}

void PEERSDK_CALLBACK OnErrorOccurred(void* tag, ErrorOccurredEventArgs const& e)
{
    printf("*** error occurred\n");
}

void PEERSDK_CALLBACK OnAudioArrived(void* tag, AudioArrivedEventArgs const& e)
{
	switch (e.Type())
	{
	case AudioType_IMA_ADPCM_16Bits_8000Hz:
		printf("CH[%d], AudioType: AudioType_IMA_ADPCM_16Bits_8000Hz\n", e.Channel());
		break;
	case AudioType_LPCM_16Bits_8000Hz:
		printf("CH[%d], AudioType: AudioType_LPCM_16Bits_8000Hz\n", e.Channel());
		break;
	}
	
}

void PEERSDK_CALLBACK OnVideoArrived(void* tag, VideoArrivedEventArgs const& e)
{
	
//    printf("*** video arrived: ");
    switch (e.Type())
    {
    case VideoType_H264_IFrame:
        printf("I-frame  %dx%d\n", e.Width(), e.Height());
        break;
    case VideoType_H264_PFrame:
        printf("P-frame  %dx%d\n", e.Width(), e.Height());
        break;
	case VideoType_H265_IFrame:
		printf("H.265 I-frame  %dx%d\n", e.Width(), e.Height());
		break;
	case VideoType_H265_PFrame:
		printf("H.265 P-frame  %dx%d\n", e.Width(), e.Height());
		break;
    default:
        break;
    }
}

void PEERSDK_CALLBACK OnVideoLossChanged(void* tag, VideoLossChangedEventArgs const& e)
{
    for (int i = 0; i < e.Active().Count(); i++)
    {
        printf("[%02d] video loss\n", e.Active()[i]);
    }
    for (int i = 0; i < e.Deactive().Count(); i++)
    {
        printf("[%02d] video normal\n", e.Deactive()[i]);
    }
}

void PEERSDK_CALLBACK OnVideoMotionChanged(void* tag, VideoMotionChangedEventArgs const& e)
{
    for (int i = 0; i < e.Active().Count(); i++)
    {
        printf("[%02d] video motion\n", e.Active()[i]);
    }
    for (int i = 0; i < e.Deactive().Count(); i++)
    {
        printf("[%02d] video static\n", e.Deactive()[i]);
    }
}

void GetMotionRecordListWithDay(int year, int month, int day)
{
	PeerRecordList* recordList = NULL;
    PeerResult r = m_peer->CreateRecordList(&recordList);
    if (!r)
    {
        printf("*** failed to get record list\n");
        return;
    }

	int ch;
	for ( ch = 0 ; ch < 4 ; ch++)
	{
		TimeSpanList tsList;
		r = recordList->GetMotionRecordedMinutesOfDay(year, month, day, ch, tsList);
		
		printf("\nCH[%02d] ======Time List(%02d)======\n", ch + 1,  tsList.Count());
		for (int i = 0 ; i < tsList.Count() ; i++)
			printf("CH[%02d]=>TimeRange(%02d:%02d)\n", ch + 1,  tsList[i].Hours(), tsList[i].Minutes());
	}
}

void GetMotionRecordListWithHour(int year, int month, int day)
{
	PeerRecordList* recordList = NULL;
    PeerResult r = m_peer->CreateRecordList(&recordList);
    if (!r)
    {
        printf("*** failed to get record list\n");
        return;
    }

	int ch;
	int hourIdx;
	for ( ch = 0 ; ch < 4 ; ch++)
	{
		for (hourIdx = 0 ; hourIdx < 23 ; hourIdx++)
		{
			TimeSpanList tsList;
			r = recordList->GetMotionRecordedMinutesOfHour(year, month, day, hourIdx, ch, tsList);
		
			if (tsList.Count() != 0)
			{
				printf("\nCH[%02d] ======Time List Hour[%d](%02d)======\n", ch + 1,  hourIdx, tsList.Count());
				for (int i = 0 ; i < tsList.Count() ; i++)
					printf("CH[%02d]=>TimeRange(%02d:%02d)\n", ch + 1,  tsList[i].Hours(), tsList[i].Minutes());
			}
		}
	}
}

int main()
{
    PeerResult r;

    r = Peer::Startup();
    if (!r)
    {
        printf("*** failed to initialize\n");
        return Finalize(-1);
    }

    m_peer = new Peer();
    r = m_peer->Connect("192.168.3.67", 81, "admin", "123456", "", true);
    if (!r)
    {
        printf("*** failed to connect\n");
        return Finalize(-1);
    }

    for (int i = 0; i < m_peer->Channels().Count(); i++)
    {
        PeerChannel* channel = m_peer->Channels()[i];

        String s = channel->Name();
#if defined(ICARCH_WIN32)
        wprintf(L"[%02d] %s", i, (LPCWSTR)s);
#elif defined(ICARCH_IOS_ARM7)
#endif
        if (channel->Audio()->IsPresent())
            printf("    Has audio\n");
        else
            printf("    No audio\n");
    }

	GetMotionRecordListWithHour( 2018, 11, 21);
	GetMotionRecordListWithDay( 2018, 11, 21);
	
	system("PAUSE");

    m_peer->ErrorOccurred().Add(NULL, OnErrorOccurred);
    m_peer->VideoLossChanged().Add(NULL, OnVideoLossChanged);
    m_peer->VideoMotionChanged().Add(NULL, OnVideoMotionChanged);

	r = m_peer->CreateLiveStream(&m_stream);
    if (!r)
    {
        printf("*** failed to create live stream\n");
        return Finalize(-1);
    }

    //m_stream->ErrorOccurred().Add(NULL, OnStreamErrorOccurred);
    m_stream->VideoArrived().Add(NULL, OnVideoArrived);
	m_stream->AudioArrived().Add(NULL, OnAudioArrived);
    m_stream->SetActive(1);
    m_stream->SetChannelMask(0xFFFF, 0xFFFF);
    m_stream->Start();

    while (true)
    {
        char c;
        while ((c = (char) getchar()) != EOF)
        {
            if ( c == 'w')
                m_peer->Channels()[0]->Video()->PTZ()->Move(0,20,false);
            else if(c == 's')
                m_peer->Channels()[0]->Video()->PTZ()->Move(0,-20,false);
            else if(c == 'a' )
                m_peer->Channels()[0]->Video()->PTZ()->Move(-100, 1,false);
            else if(c == 'd')
                m_peer->Channels()[0]->Video()->PTZ()->Move(20, 0,false);

        }
        Sleep(1000);
        m_peer->Channels()[2]->Video()->PTZ()->Stop();
        printf("%d\n", c);
    }
    
    while (true)
    {
        char c = 0;
        scanf("%c", &c);
        if (c == 'q')
            break;
    }

    return Finalize(0);
}
