/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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.
 */

#include <stdint.h>
#include <limits.h>
#include <sys/types.h>
#include <math.h>

#include <utils/threads.h>
#include <utils/Errors.h>
#include <utils/Log.h>

#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/DisplayInfo.h>
#include <ui/ISurfaceComposer.h>
#include <ui/ISurfaceFlingerClient.h>

#include <pixelflinger/pixelflinger.h>

#include "CPUGauge.h"

namespace android {

CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
                    nsecs_t interval,
                    int clock,
                    int refclock)
    :   Thread(false), 
        mInterval(interval), mClock(clock), mRefClock(refclock),
        mReferenceTime(0),
        mReferenceWorkingTime(0), mCpuUsage(0),
        mRefIdleTime(0), mIdleTime(0)
{
    mFd = fopen("/proc/stat", "r");
    setvbuf(mFd, NULL, _IONBF, 0);

    mSession = SurfaceComposerClient::clientForConnection(
        composer->createConnection()->asBinder());
}

CPUGauge::~CPUGauge()
{
    fclose(mFd);
}

const sp<SurfaceComposerClient>& CPUGauge::session() const 
{
    return mSession;
}

void CPUGauge::onFirstRef()
{
    run("CPU Gauge");
}

status_t CPUGauge::readyToRun()
{
    LOGI("Starting CPU gauge...");
    return NO_ERROR;
}

bool CPUGauge::threadLoop()
{
    DisplayInfo dinfo;
    session()->getDisplayInfo(0, &dinfo);
    sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
    session()->openTransaction();
    s->setLayer(INT_MAX);
    session()->closeTransaction();
    
    static const GGLfixed colors[4][4] = {
            { 0x00000, 0x10000, 0x00000, 0x10000 },
            { 0x10000, 0x10000, 0x00000, 0x10000 },
            { 0x10000, 0x00000, 0x00000, 0x10000 },
            { 0x00000, 0x00000, 0x00000, 0x10000 },
        };

    GGLContext* gl;
    gglInit(&gl);
    gl->activeTexture(gl, 0);
    gl->disable(gl, GGL_TEXTURE_2D);
    gl->disable(gl, GGL_BLEND);

    const int w = dinfo.w;

    while(!exitPending())
    {
        mLock.lock();
            const float cpuUsage = this->cpuUsage();
            const float totalCpuUsage = 1.0f - idle();
        mLock.unlock();

        Surface::SurfaceInfo info;
        s->lock(&info);
            GGLSurface fb;
                fb.version = sizeof(GGLSurface);
                fb.width   = info.w;
                fb.height  = info.h;
                fb.stride  = info.s;
                fb.format  = info.format;
                fb.data = (GGLubyte*)info.bits;

            gl->colorBuffer(gl, &fb);
            gl->color4xv(gl, colors[3]);
            gl->recti(gl, 0, 0, w, 4);
            gl->color4xv(gl, colors[2]); // red
            gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
            gl->color4xv(gl, colors[0]); // green
            gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
        
        s->unlockAndPost(); 

        usleep(ns2us(mInterval));
    }

    gglUninit(gl);
    return false;
}

void CPUGauge::sample()
{
    if (mLock.tryLock() == NO_ERROR) {
        const nsecs_t now = systemTime(mRefClock);
        const nsecs_t referenceTime = now-mReferenceTime;
        if (referenceTime >= mInterval) {
            const float reftime = 1.0f / referenceTime;
            const nsecs_t nowWorkingTime = systemTime(mClock);
            
            char buf[256];
            fgets(buf, 256, mFd);
            rewind(mFd);
            char *str = buf+5;
            char const * const usermode = strsep(&str, " ");  (void)usermode;
            char const * const usernice = strsep(&str, " ");  (void)usernice;
            char const * const systemmode = strsep(&str, " ");(void)systemmode;
            char const * const idle = strsep(&str, " ");
            const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
            mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
            mRefIdleTime = nowIdleTime;
            
            const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
            const float newCpuUsage = float(workingTime) * reftime;
            if (mCpuUsage != newCpuUsage) {        
                mCpuUsage = newCpuUsage;
                mReferenceWorkingTime = nowWorkingTime;
                mReferenceTime = now;
            }
        }
        mLock.unlock();
    }
}


}; // namespace android
