#include "dxpcconf.h"

#include <stdlib.h>
#include "ClientCache.H"
#include "constants.H"


// Histograms used to build static Huffman codes for run-length-encoding
// of images...generated by profiling lots of bitmapped text and images
// produced by FrameMaker

static const unsigned int PIXEL_COUNT_0 = 63;
static const unsigned int PixelHistogram0[PIXEL_COUNT_0] = {
    82551,
    69015,
    30616,
    24739,
    15491,
    10108,
    7422,
    7569,
    3408,
    3457,
    2013,
    2144,
    3527,
    3187,
    2883,
    1717,
    1487,
    1024,
    789,
    618,
    993,
    1029,
    664,
    711,
    667,
    736,
    572,
    492,
    909,
    432,
    422,
    306,
    269,
    265,
    522,
    445,
    249,
    210,
    252,
    150,
    189,
    181,
    253,
    217,
    251,
    272,
    183,
    231,
    198,
    186,
    177,
    196,
    134,
    287,
    190,
    327,
    150,
    155,
    119,
    138,
    230,
    262
};
static const unsigned int PIXEL_OVERFLOW_COUNT_0 = 15400;

static const unsigned int PIXEL_COUNT_1 = 32;
static const unsigned int PixelHistogram1[PIXEL_COUNT_1] = {
    181385,
    57253,
    51214,
    19913,
    14296,
    8104,
    3138,
    1706,
    1985,
    1244,
    1011,
    581,
    869,
    327,
    456,
    397,
    661,
    191,
    198,
    155,
    95,
    76,
    28,
    18,
    10,
    3,
    3,
    11,
    2,
    0,
    6,
    2
};
static const unsigned int PIXEL_OVERFLOW_COUNT_1 = 4;


static const unsigned int COLUMN_PIXEL_COUNT_0 = 32;
static const unsigned int ColumnPixelHistogram0[COLUMN_PIXEL_COUNT_0] = {
    4646,
    5347,
    7237,
    10526,
    11306,
    4105,
    2643,
    1766,
    6663,
    3805,
    2908,
    1225,
    502,
    1161,
    758,
    363,
    186,
    75,
    61,
    513,
    120,
    4,
    21,
    4,
    0,
    0,
    29,
    1,
    0,
    0,
    0,
    0
};


static const unsigned int COLUMN_PIXEL_COUNT_1 = 32;
static const unsigned int ColumnPixelHistogram1[COLUMN_PIXEL_COUNT_1] = {
    20339,
    8153,
    4903,
    2193,
    933,
    310,
    1024,
    402,
    486,
    645,
    598,
    132,
    162,
    92,
    35,
    5,
    3,
    7,
    10,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
};


// Precomputed static prefix code for encoding of run length deltas
// between scan lines...based on Group 4 FAX encoding.  (Reference:
// "FAX: Digital Facsimile Technology and Applications," 2nd Edition;
// McConnel, Bodson, and Schaphorst; Artech House, 1992; ISBN 0-89006-495-4)
static const char *ScanLineDiffCodes[SD_NUM_CODES] = {
    "0",                        // Vertical +0
    "100",                      // Vertical +1
    "110",                      // Vertical -1
    "101",                      // Horizontal
    "1111",                     // Pass
    "11100",                    // Vertical +2
    "11101",                    // Vertical -2
};



ClientCache::ClientCache():
cursorCache(16), gcCache(16), drawableCache(16), windowCache(16),
colormapCache(16), visualCache(16), lastFont(0), lastRequestSequenceNum(0),
lastOpcode(0),
changePropertyPropertyCache(16), changePropertyTypeCache(16),
changePropertyData32Cache(16),
changePropertyTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
configureWindowBitmaskCache(4),
convertSelectionRequestorCache(16),
convertSelectionLastTimestamp(0),
copyPlaneBitPlaneCache(8),
createGCBitmaskCache(8),
createPixmapLastPixmap(0), createPixmapXCache(8), createPixmapYCache(8),
createWindowBitmaskCache(8),
fillPolyNumPointsCache(8), fillPolyIndex(0),
getSelectionOwnerSelectionCache(8),
grabButtonEventMaskCache(8), grabButtonConfineCache(8),
grabButtonModifierCache(8),
grabKeyboardLastTimestamp(0),
imageText8LastX(0), imageText8LastY(0), imageText8CacheX(8),
imageText8CacheY(8), imageText8TextCompressor(textCache,
                                              CLIENT_TEXT_CACHE_SIZE),
internAtomTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
openFontTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
polySegmentCacheX(8), polySegmentCacheY(8), polySegmentCacheIndex(0),
polyText8LastX(0), polyText8LastY(0), polyText8CacheX(8),
polyText8CacheY(8), polyText8FontCache(8),
polyText8TextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
putImageWidthCache(8), putImageHeightCache(8), putImageLastX(0),
putImageLastY(0), putImageXCache(8), putImageYCache(8),
putImagePixel0Coder(PIXEL_COUNT_0, PixelHistogram0, PIXEL_OVERFLOW_COUNT_0),
putImagePixel1Coder(PIXEL_COUNT_1, PixelHistogram1, PIXEL_OVERFLOW_COUNT_1),
putImageDiffCoder(SD_NUM_CODES, ScanLineDiffCodes),
putImageLastPixels(3),
columnPixel0Coder(COLUMN_PIXEL_COUNT_0, ColumnPixelHistogram0, 0),
columnPixel1Coder(COLUMN_PIXEL_COUNT_1, ColumnPixelHistogram1, 0),
putImageReferenceLine(NULL), putImageCodingLine(NULL),
putImageLineSize(0),
queryColorsLastPixel(0),
setClipRectanglesXCache(8), setClipRectanglesYCache(8),
setDashesLengthCache(8), setDashesOffsetCache(8),
setSelectionOwnerCache(8), setSelectionOwnerTimestampCache(8),
translateCoordsSrcCache(8), translateCoordsDestCache(8),
translateCoordsXCache(8), translateCoordsYCache(8)
{
    unsigned int i;

    for (i = 0; i < 3; i++)
    {
        allocColorRGBCache[i] = new IntCache(8);
        convertSelectionAtomCache[i] = new IntCache(8);
    }

    for (i = 0; i < 4; i++)
        clearAreaGeomCache[i] = new IntCache(8);

    for (i = 0; i < 7; i++)
        configureWindowAttrCache[i] = new IntCache(8);

    for (i = 0; i < 6; i++)
    {
        copyAreaGeomCache[i] = new IntCache(8);
        copyPlaneGeomCache[i] = new IntCache(8);
    }

    for (i = 0; i < 23; i++)
        createGCAttrCache[i] = new IntCache(CREATEGC_FIELD_WIDTH[i]);

    for (i = 0; i < 6; i++)
        createWindowGeomCache[i] = new IntCache(8);
    for (i = 0; i < 15; i++)
        createWindowAttrCache[i] = new IntCache(8);

    for (i = 0; i < FILL_POLY_MAX_POINTS; i++)
    {
        fillPolyXRelCache[i] = new IntCache(8);
        fillPolyXAbsCache[i] = new IntCache(8);
        fillPolyYRelCache[i] = new IntCache(8);
        fillPolyYAbsCache[i] = new IntCache(8);
    }
    for (i = 0; i < 8; i++)
    {
        fillPolyRecentX[i] = 0;
        fillPolyRecentY[i] = 0;
    }

    for (i = 0; i < 2; i++)
    {
        polyFillRectangleCacheX[i] = new IntCache(8);
        polyFillRectangleCacheY[i] = new IntCache(8);
        polyFillRectangleCacheWidth[i] = new IntCache(8);
        polyFillRectangleCacheHeight[i] = new IntCache(8);
    }

    for (i = 0; i < 2; i++)
    {
        polyLineCacheX[i] = new IntCache(8);
        polyLineCacheY[i] = new IntCache(8);
    }

    for (i = 0; i < 2; i++)
    {
        polyPointCacheX[i] = new IntCache(8);
        polyPointCacheY[i] = new IntCache(8);
    }

    for (i = 0; i < 4; i++)
        polyRectangleGeomCache[i] = new IntCache(8);

    for (i = 0; i < 2; i++)
    {
        polySegmentLastX[i] = 0;
        polySegmentLastY[i] = 0;
    }

    for (i = 0; i < 4; i++)
        setClipRectanglesGeomCache[i] = new IntCache(8);
}


ClientCache::~ClientCache()
{
    unsigned int i;

    for (i = 0; i < 3; i++)
    {
        delete allocColorRGBCache[i];
        delete convertSelectionAtomCache[i];
    }

    for (i = 0; i < 4; i++)
        delete clearAreaGeomCache[i];

    for (i = 0; i < 7; i++)
        delete configureWindowAttrCache[i];

    for (i = 0; i < 6; i++)
    {
        delete copyAreaGeomCache[i];
        delete copyPlaneGeomCache[i];
    }

    for (i = 0; i < 23; i++)
        delete createGCAttrCache[i];

    for (i = 0; i < 6; i++)
        delete createWindowGeomCache[i];

    for (i = 0; i < 15; i++)
        delete createWindowAttrCache[i];

    for (i = 0; i < FILL_POLY_MAX_POINTS; i++)
    {
        delete fillPolyXRelCache[i];
        delete fillPolyXAbsCache[i];
        delete fillPolyYRelCache[i];
        delete fillPolyYAbsCache[i];
    }

    for (i = 0; i < 2; i++)
    {
        delete polyFillRectangleCacheX[i];
        delete polyFillRectangleCacheY[i];
        delete polyFillRectangleCacheWidth[i];
        delete polyFillRectangleCacheHeight[i];
    }

    for (i = 0; i < 2; i++)
    {
        delete polyLineCacheX[i];
        delete polyLineCacheY[i];
    }

    for (i = 0; i < 2; i++)
    {
        delete polyPointCacheX[i];
        delete polyPointCacheY[i];
    }

    for (i = 0; i < 4; i++)
        delete polyRectangleGeomCache[i];

    delete[]putImageReferenceLine;
    delete[]putImageCodingLine;

    for (i = 0; i < 4; i++)
        delete setClipRectanglesGeomCache[i];
}
