/*
 * Copyright (C) 2010 The Android Open Source Project
 * Copyright (C) 2012, The Linux Foundation. All rights reserved.
 *
 * Not a Contribution, Apache license notifications and license are
 * retained for attribution purposes only.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define DEBUG 0
#include <ctype.h>
#include <fcntl.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioSystem.h>
#include <utils/threads.h>
#include <utils/Errors.h>
#include <utils/Log.h>

#include <linux/msm_mdp.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/resource.h>
#include <cutils/properties.h>
#include "hwc_utils.h"
#include "external.h"
#include "overlayUtils.h"
#include "overlay.h"

using namespace android;

namespace qhwc {

#define MAX_FRAME_BUFFER_NAME_SIZE      (80)
#define MAX_DISPLAY_DEVICES             (3)


const char* msmFbDevicePath[] = {  "/dev/graphics/fb1",
                                   "/dev/graphics/fb2"};

/*
 * Updates extDeviceFbIndex Array with the correct frame buffer indices
 * of avaiable external devices
 *
 */
void ExternalDisplay::updateExtDispDevFbIndex()
{
    FILE *displayDeviceFP = NULL;
    char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
    char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];

    for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) {
        sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j);
        displayDeviceFP = fopen(msmFbTypePath, "r");
        if(displayDeviceFP){
            fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
                    displayDeviceFP);
            if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){
                ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j);
                mHdmiFbNum = j;
            } else if(strncmp(fbType, "writeback panel",
                                    strlen("writeback panel")) == 0){
                ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j);
                mWfdFbNum = j;
            }
            fclose(displayDeviceFP);
        }
    }
    ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__,
                                                       mHdmiFbNum, mWfdFbNum);
}

int ExternalDisplay::configureHDMIDisplay() {
    openFrameBuffer(mHdmiFbNum);
    if(mFd == -1)
        return -1;
    readResolution();
    //Get the best mode and set
    // TODO: Move this to activate
    setResolution(getBestMode());
    setDpyHdmiAttr();
    setExternalDisplay(true, mHdmiFbNum);
    return 0;
}

int ExternalDisplay::configureWFDDisplay() {
    int ret = 0;
    if(mConnectedFbNum == mHdmiFbNum) {
        ALOGE("%s: Cannot process WFD connection while HDMI is active",
                     __FUNCTION__);
        return -1;
    }
    openFrameBuffer(mWfdFbNum);
    if(mFd == -1)
        return -1;
    ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
    if(ret < 0) {
        ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
                strerror(errno));
    }
    setDpyWfdAttr();
    setExternalDisplay(true, mWfdFbNum);
    return 0;
}

int ExternalDisplay::teardownHDMIDisplay() {
    if(mConnectedFbNum == mHdmiFbNum) {
        // hdmi offline event..!
        closeFrameBuffer();
        resetInfo();
        setExternalDisplay(false);
    }
    return 0;
}

int ExternalDisplay::teardownWFDDisplay() {
    if(mConnectedFbNum == mWfdFbNum) {
        // wfd offline event..!
        closeFrameBuffer();
        memset(&mVInfo, 0, sizeof(mVInfo));
        setExternalDisplay(false);
    }
    return 0;
}

void ExternalDisplay::processUEventOnline(const char *str) {
    const char *s1 = str + strlen("change@/devices/virtual/switch/");
    if(!strncmp(s1,"hdmi",strlen(s1))) {
        // hdmi online event..!
        configureHDMIDisplay();
    }else if(!strncmp(s1,"wfd",strlen(s1))) {
        // wfd online event..!
        configureWFDDisplay();
    }
}

void ExternalDisplay::processUEventOffline(const char *str) {
    const char *s1 = str + strlen("change@/devices/virtual/switch/");
    if(!strncmp(s1,"hdmi",strlen(s1))) {
        teardownHDMIDisplay();
    }else if(!strncmp(s1,"wfd",strlen(s1))) {
        teardownWFDDisplay();
    }
}

ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
    mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
    mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
{
    memset(&mVInfo, 0, sizeof(mVInfo));
    //Determine the fb index for external display devices.
    updateExtDispDevFbIndex();
}

void ExternalDisplay::setEDIDMode(int resMode) {
    ALOGD_IF(DEBUG,"resMode=%d ", resMode);
    {
        Mutex::Autolock lock(mExtDispLock);
        setExternalDisplay(false);
        openFrameBuffer(mHdmiFbNum);
        setResolution(resMode);
    }
    setExternalDisplay(true, mHdmiFbNum);
}

void ExternalDisplay::setHPD(uint32_t startEnd) {
    ALOGD_IF(DEBUG,"HPD enabled=%d", startEnd);
    writeHPDOption(startEnd);
}

void ExternalDisplay::setActionSafeDimension(int w, int h) {
    ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
    Mutex::Autolock lock(mExtDispLock);
    overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
    setExternalDisplay(true, mHdmiFbNum);
}

int ExternalDisplay::getModeCount() const {
    ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
    Mutex::Autolock lock(mExtDispLock);
    return mModeCount;
}

void ExternalDisplay::getEDIDModes(int *out) const {
    Mutex::Autolock lock(mExtDispLock);
    for(int i = 0;i < mModeCount;i++) {
        out[i] = mEDIDModes[i];
    }
}

ExternalDisplay::~ExternalDisplay()
{
    closeFrameBuffer();
}

struct disp_mode_timing_type {
    int  video_format;

    int  active_h;
    int  active_v;

    int  front_porch_h;
    int  pulse_width_h;
    int  back_porch_h;

    int  front_porch_v;
    int  pulse_width_v;
    int  back_porch_v;

    int  pixel_freq;
    bool interlaced;

    void set_info(struct fb_var_screeninfo &info) const;
};

void disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const
{
    info.reserved[0] = 0;
    info.reserved[1] = 0;
    info.reserved[2] = 0;
    info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16);

    info.xoffset = 0;
    info.yoffset = 0;
    info.xres = active_h;
    info.yres = active_v;

    info.pixclock = pixel_freq*1000;
    info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;

    info.right_margin = front_porch_h;
    info.hsync_len = pulse_width_h;
    info.left_margin = back_porch_h;
    info.lower_margin = front_porch_v;
    info.vsync_len = pulse_width_v;
    info.upper_margin = back_porch_v;
}

/* Video formates supported by the HDMI Standard */
/* Indicates the resolution, pix clock and the aspect ratio */
#define m640x480p60_4_3         1
#define m720x480p60_4_3         2
#define m720x480p60_16_9        3
#define m1280x720p60_16_9       4
#define m1920x1080i60_16_9      5
#define m1440x480i60_4_3        6
#define m1440x480i60_16_9       7
#define m1920x1080p60_16_9      16
#define m720x576p50_4_3         17
#define m720x576p50_16_9        18
#define m1280x720p50_16_9       19
#define m1440x576i50_4_3        21
#define m1440x576i50_16_9       22
#define m1920x1080p50_16_9      31
#define m1920x1080p24_16_9      32
#define m1920x1080p25_16_9      33
#define m1920x1080p30_16_9      34

static struct disp_mode_timing_type supported_video_mode_lut[] = {
    {m640x480p60_4_3,     640,  480,  16,  96,  48, 10, 2, 33,  25200, false},
    {m720x480p60_4_3,     720,  480,  16,  62,  60,  9, 6, 30,  27030, false},
    {m720x480p60_16_9,    720,  480,  16,  62,  60,  9, 6, 30,  27030, false},
    {m1280x720p60_16_9,  1280,  720, 110,  40, 220,  5, 5, 20,  74250, false},
    {m1920x1080i60_16_9, 1920,  540,  88,  44, 148,  2, 5,  5,  74250, false},
    {m1440x480i60_4_3,   1440,  240,  38, 124, 114,  4, 3, 15,  27000, true},
    {m1440x480i60_16_9,  1440,  240,  38, 124, 114,  4, 3, 15,  27000, true},
    {m1920x1080p60_16_9, 1920, 1080,  88,  44, 148,  4, 5, 36, 148500, false},
    {m720x576p50_4_3,     720,  576,  12,  64,  68,  5, 5, 39,  27000, false},
    {m720x576p50_16_9,    720,  576,  12,  64,  68,  5, 5, 39,  27000, false},
    {m1280x720p50_16_9,  1280,  720, 440,  40, 220,  5, 5, 20,  74250, false},
    {m1440x576i50_4_3,   1440,  288,  24, 126, 138,  2, 3, 19,  27000, true},
    {m1440x576i50_16_9,  1440,  288,  24, 126, 138,  2, 3, 19,  27000, true},
    {m1920x1080p50_16_9, 1920, 1080, 528,  44, 148,  4, 5, 36, 148500, false},
    {m1920x1080p24_16_9, 1920, 1080, 638,  44, 148,  4, 5, 36,  74250, false},
    {m1920x1080p25_16_9, 1920, 1080, 528,  44, 148,  4, 5, 36,  74250, false},
    {m1920x1080p30_16_9, 1920, 1080,  88,  44, 148,  4, 5, 36,  74250, false},
};

int ExternalDisplay::parseResolution(char* edidStr, int* edidModes)
{
    char delim = ',';
    int count = 0;
    char *start, *end;
    // EDIDs are string delimited by ','
    // Ex: 16,4,5,3,32,34,1
    // Parse this string to get mode(int)
    start = (char*) edidStr;
    end = &delim;
    while(*end == delim) {
        edidModes[count] = (int) strtol(start, &end, 10);
        start = end+1;
        count++;
    }
    ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count);
    for (int i = 0; i < count; i++)
        ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]);
    return count;
}

bool ExternalDisplay::readResolution()
{
    char sysFsEDIDFilePath[255];
    sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes",
            mHdmiFbNum);

    int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
    int len = -1;

    if (hdmiEDIDFile < 0) {
        ALOGE("%s: edid_modes file '%s' not found",
                 __FUNCTION__, sysFsEDIDFilePath);
        return false;
    } else {
        len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
        ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
                 __FUNCTION__, mEDIDs, len);
        if ( len <= 0) {
            ALOGE("%s: edid_modes file empty '%s'",
                     __FUNCTION__, sysFsEDIDFilePath);
        }
        else {
            while (len > 1 && isspace(mEDIDs[len-1]))
                --len;
            mEDIDs[len] = 0;
        }
    }
    close(hdmiEDIDFile);
    if(len > 0) {
        // Get EDID modes from the EDID strings
        mModeCount = parseResolution(mEDIDs, mEDIDModes);
        ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
                 mModeCount);
    }

    return (strlen(mEDIDs) > 0);
}

bool ExternalDisplay::openFrameBuffer(int fbNum)
{
    if (mFd == -1) {
        mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
        if (mFd < 0)
            ALOGE("%s: %s is not available", __FUNCTION__,
                                            msmFbDevicePath[fbNum-1]);
        if(mHwcContext) {
            mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
        }
    }
    return (mFd > 0);
}

bool ExternalDisplay::closeFrameBuffer()
{
    int ret = 0;
    if(mFd > 0) {
        ret = close(mFd);
        mFd = -1;
    }
    if(mHwcContext) {
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
    }
    return (ret == 0);
}

// clears the vinfo, edid, best modes
void ExternalDisplay::resetInfo()
{
    memset(&mVInfo, 0, sizeof(mVInfo));
    memset(mEDIDs, 0, sizeof(mEDIDs));
    memset(mEDIDModes, 0, sizeof(mEDIDModes));
    mModeCount = 0;
    mCurrentMode = -1;
}

int ExternalDisplay::getModeOrder(int mode)
{
    switch (mode) {
        default:
        case m1440x480i60_4_3:
            return 1; // 480i 4:3
        case m1440x480i60_16_9:
            return 2; // 480i 16:9
        case m1440x576i50_4_3:
            return 3; // i576i 4:3
        case m1440x576i50_16_9:
            return 4; // 576i 16:9
        case m640x480p60_4_3:
            return 5; // 640x480 4:3
        case m720x480p60_4_3:
            return 6; // 480p 4:3
        case m720x480p60_16_9:
            return 7; // 480p 16:9
        case m720x576p50_4_3:
            return 8; // 576p 4:3
        case m720x576p50_16_9:
            return 9; // 576p 16:9
        case m1920x1080i60_16_9:
            return 10; // 1080i 16:9
        case m1280x720p50_16_9:
            return 11; // 720p@50Hz
        case m1280x720p60_16_9:
            return 12; // 720p@60Hz
        case m1920x1080p24_16_9:
            return 13; //1080p@24Hz
        case m1920x1080p25_16_9:
            return 14; //108-p@25Hz
        case m1920x1080p30_16_9:
            return 15; //1080p@30Hz
        case m1920x1080p50_16_9:
            return 16; //1080p@50Hz
        case m1920x1080p60_16_9:
            return 17; //1080p@60Hz
    }
}

// Get the best mode for the current HD TV
int ExternalDisplay::getBestMode() {
    int bestOrder = 0;
    int bestMode = m640x480p60_4_3;
    Mutex::Autolock lock(mExtDispLock);
    // for all the edid read, get the best mode
    for(int i = 0; i < mModeCount; i++) {
        int mode = mEDIDModes[i];
        int order = getModeOrder(mode);
        if (order > bestOrder) {
            bestOrder = order;
            bestMode = mode;
        }
    }
    return bestMode;
}

inline bool ExternalDisplay::isValidMode(int ID)
{
    return ((ID >= m640x480p60_4_3) && (ID <= m1920x1080p30_16_9));
}

void ExternalDisplay::setResolution(int ID)
{
    struct fb_var_screeninfo info;
    int ret = 0;
    ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
    if(ret < 0) {
        ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
                                                            strerror(errno));
    }

    ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
            "(%d,%d,%d) %dMHz>", __FUNCTION__,
            mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
            mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
            mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
            mVInfo.pixclock/1000/1000);
    //If its a valid mode and its a new ID - update var_screeninfo
    if ((isValidMode(ID)) && mCurrentMode != ID) {
        const struct disp_mode_timing_type *mode =
            &supported_video_mode_lut[0];
        unsigned count =  sizeof(supported_video_mode_lut)/sizeof
            (*supported_video_mode_lut);
        for (unsigned int i = 0; i < count; ++i) {
            const struct disp_mode_timing_type *cur =
                &supported_video_mode_lut[i];
            if (cur->video_format == ID)
                mode = cur;
        }
        mode->set_info(mVInfo);
        ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
                 "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
                 mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
                 mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
                 mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
                 mVInfo.pixclock/1000/1000);
        mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
        ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
        if(ret < 0) {
            ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
                                                 __FUNCTION__, strerror(errno));
        }
        mCurrentMode = ID;
    }
}

void ExternalDisplay::setExternalDisplay(bool connected, int extFbNum)
{
    hwc_context_t* ctx = mHwcContext;
    if(ctx) {
        ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected);
        // Store the external display
        mConnected = connected;
        mConnectedFbNum = extFbNum;
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
        // Update external fb number in Overlay context
        overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
    }
}

int ExternalDisplay::getExtFbNum(int &fbNum) {
    int ret = -1;
    if(mConnected) {
        fbNum = mConnectedFbNum;
        ret = 0;
    }
    return ret;
}

bool ExternalDisplay::writeHPDOption(int userOption) const
{
    bool ret = true;
    char sysFsHPDFilePath[255];
    sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd",
                                mHdmiFbNum);
    int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0);
    if (hdmiHPDFile < 0) {
        ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__,
                                sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
        ret = false;
    } else {
        int err = -1;
        ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
        if(userOption)
            err = write(hdmiHPDFile, "1", 2);
        else
            err = write(hdmiHPDFile, "0" , 2);
        if (err <= 0) {
            ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
            ret = false;
        }
        close(hdmiHPDFile);
    }
    return ret;
}

/*
 * commits the changes to the external display
 */
bool ExternalDisplay::post()
{
    if(mFd == -1)
        return false;
    struct mdp_display_commit ext_commit;
    memset(&ext_commit, 0, sizeof(struct mdp_display_commit));
    ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
    if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) {
        ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
                __FUNCTION__, strerror(errno));
        return false;
    }
    return true;
}

void ExternalDisplay::setDpyWfdAttr() {
    if(mHwcContext) {
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = mVInfo.xres;
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = mVInfo.yres;
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
                1000000000l /60;
        ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
    }
}

void ExternalDisplay::setDpyHdmiAttr() {
    int width = 0, height = 0, fps = 0;
    getAttrForMode(width, height, fps);
    if(mHwcContext) {
        ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height);
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
        mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
            1000000000l / fps;
    }
}

void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
    switch (mCurrentMode) {
        case m640x480p60_4_3:
            width = 640;
            height = 480;
            fps = 60;
            break;
        case m720x480p60_4_3:
        case m720x480p60_16_9:
            width = 720;
            height = 480;
            fps = 60;
            break;
        case m720x576p50_4_3:
        case m720x576p50_16_9:
            width = 720;
            height = 576;
            fps = 50;
            break;
        case m1280x720p50_16_9:
            width = 1280;
            height = 720;
            fps = 50;
            break;
        case m1280x720p60_16_9:
            width = 1280;
            height = 720;
            fps = 60;
            break;
        case m1920x1080p24_16_9:
            width = 1920;
            height = 1080;
            fps = 24;
            break;
        case m1920x1080p25_16_9:
            width = 1920;
            height = 1080;
            fps = 25;
            break;
        case m1920x1080p30_16_9:
            width = 1920;
            height = 1080;
            fps = 30;
            break;
        case m1920x1080p50_16_9:
            width = 1920;
            height = 1080;
            fps = 50;
            break;
        case m1920x1080p60_16_9:
            width = 1920;
            height = 1080;
            fps = 60;
            break;
    }
}

};
