/*---------------------------------------------------------------------------*/
/* image_buffer.cpp                                                          */
/* copyright (c) innovaphone 2016                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#include "platform/platform.h"

#include "common/os/iomux.h"

#include "common/interface/task.h"
#include "common/interface/stask.h"
#include "common/interface/socket.h"
#include "common/interface/media.h"
#include "common/interface/appsharing.h"
#include "common/interface/video_format_conversion.h"
#include "common/lib/tasks_file.h"
#include "common/lib/language.h"
#include "client/lang/myapps_languages.h"
#include "client/logflags/debug_logflags.h"
#include "client/config/debug_readlog.h"
#include "client/linux/client_main/appclient_main.h"

#include "image_buffer.h"

#define ICON_DESKTOP_BASE64\
    "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACmUlEQVRYw+2WWU9T"\
    "URSF29LJllqgA4VSoFYpCCLO0RhN/CPiPGD01Xk2/obzJLWl1AHn4dF/drdr9Z5D"\
    "D7U1QsuT3cnKfbg3+dYezj7X4+lFL3ph4vYv2W55LbU0kK05HSlQEvG8asgL+ZZF"\
    "+iA/3vF9EOq7sw0G+ssbwQZKYOi1SBjaAUWg4N0uG0isOBvAJlMDjcIcDcYqrsLd"\
    "NDCy6tTLTPmXG+BI2QUTuBOKr4gMQINQ5F4XDYRKLjygS20yjmkogUNVkQSUhFKr"\
    "eHe/SwaYmYGbrPsJrrhgA00DOgxlaiIjUPxBFwwkq84fcGY9oDM2YAPNvhEZg3LQ"\
    "4MMODbDvgVIDHrXgCV3mYQuceysyDk1Ak+/wzaMODbDPHLhQU+YJK+usztZAd0GF"\
    "9yK7oVQnBuIVp37UOO000g4+boEJnVoTKULTH/DN4y0aSFed9XNuSs+BG9Jlt+F5"\
    "nfEeDZ4BeC8091Fk9MkWDJi+0wCPnik9p50DN9wCPqXBs4Dug+Y/ieyHxp5uwQBX"\
    "KDedyZ6bLW6VfrTmDttkE3xOgxc+ixyEDn2ByWebNGBWrU/3vjl7U3oOHHtuw5nx"\
    "AQ0+Ah37CpObMZDRq5YGzOTbvbezz+uBm15zyz6v4Yc1+Pg3kRNQ4fkmDJgrtrn8"\
    "ZvK54Vplz54vWHCCT34XOfUDg/niHw3YV6zZeubosfwpXX5uONP7opU9e35UZ074"\
    "acDP/MQ37Qw4DsC3ynUll0riOavW5V1U4j+nJHheSRiKXlASu6gkfknJ4GUlyStK"\
    "0lDmqpLRa0py15VMLClhFG64z+JN9znzso2Bv8kH+fEnw58J3ucR3Gi81XixcLdz"\
    "vaawYLhkeM551DjteYg9Z9mZOeGzLQ30ohf/a/wGPD/Hf48PbZYAAAAASUVORK5C"\
    "YII="

extern class UAppClientMain * appClientMainUser;


class IImageBuffer * IImageBuffer::CreateImageBuffer(class IIoMux * const iomux, UImageBuffer * const user, class IInstanceLog * const log, class MediaConfiguration * mediaConfiguration)
{
    return new class ImageBuffer(iomux, user, log, mediaConfiguration);
}

class ImageBuffer *theImageBuffer;

ImageBuffer::ImageBuffer(class IIoMux * const iomux, UImageBuffer * const user, class IInstanceLog * const log, class MediaConfiguration * mediaConfiguration) : 
    iomux(iomux), 
    log(log), 
    user(user)
{
    theImageBuffer = this;
    this->mediaConfiguration = mediaConfiguration;
    yuvBuffer = NULL;
    started = false;
}

ImageBuffer::~ImageBuffer() 
{
    if (yuvBuffer) free(yuvBuffer);
}

void ImageBuffer::Capture(unsigned int appId, class IScreenBuffer * screenBuffer, int coder)
{
    if (!started) {
        started = true;
        appClientMainUser->AppClientMainStartScreenCapture();
    }
}

void ImageBuffer::Clean(unsigned int appId)
{
    if (started) {
        started = false;
        appClientMainUser->AppClientMainStopScreenCapture();
    }
}

void ImageBuffer::SubscribeApplications(void)
{
    int langId = mediaConfiguration ? mediaConfiguration->langId : MYAPPS_LANGUAGE_EN;
    user->Add(0, MYAPPS_LANG_STRING(TXT_APPSHARING_PRIMARY_DESKTOP, langId), MYAPPS_LANG_STRING(TXT_APPSHARING_PRIMARY_DESKTOP, langId), NULL, ICON_DESKTOP_BASE64, NULL, NULL);
}

void ImageBuffer::UnsubscribeApplications(void)
{
}

void ImageBuffer::CloseImageBuffer(void)
{
    theImageBuffer = NULL;
    user->CloseComplete();
}

void phone_screen_capture_sample(dword timestamp, int length, const byte *sample, int width, int height, int stride, int videoFormat)
{
    unsigned yuvWidth, yuvHeight, yuvLength;

    if (theImageBuffer) {
        yuvWidth = (width <= 1920) ? width & ~1 : 1920;
        yuvHeight = (height <= 1080) ? height & ~1 : 1080;
        yuvLength = yuvWidth * yuvHeight + ((yuvWidth * yuvHeight) >> 1);
        if (!theImageBuffer->yuvBuffer || (theImageBuffer->yuvBufferLen < yuvLength)) {
            if (theImageBuffer->yuvBuffer) free(theImageBuffer->yuvBuffer);
            theImageBuffer->yuvBufferLen = yuvLength;
            theImageBuffer->yuvBuffer = (byte *)(malloc(theImageBuffer->yuvBufferLen));
        }
        IVideoFormatConversion::RGBAToYUV(theImageBuffer->yuvBuffer, yuvWidth, &sample[((height - yuvHeight) / 2) * stride + ((width - yuvWidth) / 2) * 4], stride, yuvWidth, yuvHeight, false);
        theImageBuffer->user->ImageBufferSample(0, theImageBuffer->yuvBuffer, yuvLength, yuvWidth, yuvHeight, timestamp, 100 * 90);
    }
}

void phone_screen_capture_stopped()
{
    debug->printf("phone_screen_capture_stopped");
    if (theImageBuffer) {
        theImageBuffer->user->Remove(0);
        theImageBuffer->SubscribeApplications();
    }
}
