/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * 
 *************************************************************/



// Description: Classes to cache Graphite Segments to try to improve
//              rendering performance.

#ifndef GraphiteSegmentCache_h
#define GraphiteSegmentCache_h

#include <tools/solar.h>
#include <rtl/ustring.h>

#define GRCACHE_REUSE_VECTORS 1

#include <hash_map>

class TextSourceAdaptor;
/**
* GrSegRecord stores a Graphite Segment and its associated text
*/
class GrSegRecord {
public:
    GrSegRecord(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl);

    ~GrSegRecord();

    void reuse(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl);

    void clearVectors();
    void clear();
#ifdef GRCACHE_REUSE_VECTORS
    void setGlyphVectors(long nWidth, GraphiteLayout::Glyphs & vGlyphs, std::vector<int> vCharDxs,
                         std::vector<int> & vChar2Base, std::vector<int> & vGlyph2Char, float fScale)
    {
        clearVectors();
        mnWidth = nWidth;
        m_fontScale = fScale;
        mvGlyphs.insert(mvGlyphs.begin(), vGlyphs.begin(), vGlyphs.end());
        mvCharDxs.insert(mvCharDxs.begin(),vCharDxs.begin(),vCharDxs.end());
        mvChar2BaseGlyph.insert(mvChar2BaseGlyph.begin(),vChar2Base.begin(),vChar2Base.end());
        mvGlyph2Char.insert(mvGlyph2Char.begin(),vGlyph2Char.begin(),vGlyph2Char.end());
    }
#endif
    gr::Segment * getSegment() { return m_seg; }
    TextSourceAdaptor * getTextSrc() { return m_text; }
    void unlock() { --m_lockCount; }
    bool isRtl() const { return mbIsRtl; }
#ifdef GRCACHE_REUSE_VECTORS
    const long & width() const { return mnWidth; }
    const GraphiteLayout::Glyphs & glyphs() const { return mvGlyphs; }
    const std::vector<int> & charDxs() const { return mvCharDxs; }
    const std::vector<int> & char2BaseGlyph() const { return mvChar2BaseGlyph; }
    const std::vector<int> & glyph2Char() const { return mvGlyph2Char; }
    float & fontScale() { return m_fontScale; }
#endif
private:
    rtl::OUString * m_rope;
    TextSourceAdaptor * m_text;
    gr::Segment * m_seg;
    const xub_Unicode * m_nextKey;
    const xub_Unicode*  m_pStr;
    size_t m_startChar;
    float m_fontScale;
    long mnWidth;
    GraphiteLayout::Glyphs mvGlyphs; // glyphs in display order
    std::vector<int> mvCharDxs; // right hand side x offset of each glyph
    std::vector<int> mvChar2BaseGlyph;
    std::vector<int> mvGlyph2Char;
    bool mbIsRtl;
    int m_lockCount;
    friend class GraphiteSegmentCache;
};

typedef std::hash_map<long, GrSegRecord*, std::hash<long> > GraphiteSegMap;
typedef std::hash_multimap<size_t, GrSegRecord*> GraphiteRopeMap;
typedef std::pair<GraphiteRopeMap::iterator, GraphiteRopeMap::iterator> GrRMEntry;

/**
* GraphiteSegmentCache contains the cached Segments for one particular font size
*/
class GraphiteSegmentCache
{
public:
  enum {
    // not really sure what good values are here,
    // bucket size should be >> cache size
    SEG_BUCKET_FACTOR = 4,
    SEG_DEFAULT_CACHE_SIZE = 2047
  };
  GraphiteSegmentCache(sal_uInt32 nSegCacheSize)
    : m_segMap(nSegCacheSize * SEG_BUCKET_FACTOR),
	m_nSegCacheSize(nSegCacheSize),
    m_oldestKey(NULL) {};
  ~GraphiteSegmentCache()
  {
    m_ropeMap.clear();
    GraphiteSegMap::iterator i = m_segMap.begin();
    while (i != m_segMap.end())
    {
      GrSegRecord *r = i->second;
      delete r;
      ++i;
    }
    m_segMap.clear();
  };
  GrSegRecord * getSegment(ImplLayoutArgs & layoutArgs, bool bIsRtl, int segCharLimit)
  {
    GrSegRecord * found = NULL;
    // try to find a segment starting at correct place, if not, try to find a
    //  match for the complete buffer
    GraphiteSegMap::iterator iMap =
      m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr +
                                           layoutArgs.mnMinCharPos));
    if (iMap != m_segMap.end())
    {
      found = iMap->second;
    }
    else
    {
      iMap = m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr));
      if (iMap != m_segMap.end())
      {
        found = iMap->second;
      }
    }
    if (found)
    {
      if (found->m_seg->startCharacter() <= layoutArgs.mnMinCharPos &&
          found->m_seg->stopCharacter() >= layoutArgs.mnEndCharPos)
      {
        DBG_ASSERT(found && found->m_seg, "null entry in GraphiteSegmentCache");
        // restore original start character, in case it has changed
        found->m_seg->setTextSourceOffset(found->m_startChar);
        // check that characters are the same, at least in the range of
        // interest
        // We could use substr and ==, but substr does a copy,
        // so its probably faster to do it like this
        for (int i = layoutArgs.mnMinCharPos; i < segCharLimit; i++)
        {
          //if (!found->m_rope->match(rtl::OUString(layoutArgs.mpStr[i], layoutArgs.mnLength), i - found->m_seg->startCharacter()))
          if (found->m_rope->getStr()[i-found->m_seg->startCharacter()] != layoutArgs.mpStr[i])
            return NULL;
        }
        if (found->isRtl() != bIsRtl)
        {
            return NULL;
        }
        if (found->m_seg->stopCharacter() > layoutArgs.mnEndCharPos &&
            static_cast<int>(found->char2BaseGlyph().size()) > layoutArgs.mnEndCharPos)
        {
            // check that the requested end character isn't mid cluster
            if (found->char2BaseGlyph()[layoutArgs.mnEndCharPos-layoutArgs.mnMinCharPos] == -1)
            {
                return NULL;
            }
        }
//        if (found->m_lockCount != 0)
//          OutputDebugString("Multple users of SegRecord!");
        found->m_lockCount++;
      }
      else found = NULL;
    }
    else
    {
      // the pointers aren't the same, but we might still have the same text in a segment
      // this is expecially needed when editing a large paragraph
      // each edit changes the pointers, but if we don't reuse any segments it gets very
      // slow.
      rtl::OUString * rope = new rtl::OUString(layoutArgs.mpStr + layoutArgs.mnMinCharPos,
                                         segCharLimit - layoutArgs.mnMinCharPos);
      if (!rope) return NULL;
      size_t nHash = (*(rope)).hashCode();
      GrRMEntry range = m_ropeMap.equal_range(nHash);
      while (range.first != range.second)
      {
        found = range.first->second;
        if (found->m_lockCount == 0)
        {
          if(rope->match(*(found->m_rope)))
          {
            // found, but the pointers are all wrong
            found->m_seg->setTextSourceOffset(layoutArgs.mnMinCharPos);
            // the switch is done in graphite_layout.cxx
            //found->m_text->switchLayoutArgs(layoutArgs);
            found->m_lockCount++;
            break;
          }
          else
            found = NULL;
        }
        else
          found = NULL;
        ++(range.first);
      }
      delete rope;
    }
    return found;
  };
  GrSegRecord * cacheSegment(TextSourceAdaptor * adapter, gr::Segment * seg, bool bIsRtl);
private:
  GraphiteSegMap m_segMap;
  GraphiteRopeMap m_ropeMap;
  sal_uInt32 m_nSegCacheSize;
  const xub_Unicode * m_oldestKey;
  const xub_Unicode * m_prevKey;
};

typedef std::hash_map<int, GraphiteSegmentCache *, std::hash<int> > GraphiteCacheMap;

/**
* GraphiteCacheHandler maps a particular font, style, size to a GraphiteSegmentCache
*/
class GraphiteCacheHandler
{
public:
  GraphiteCacheHandler() : m_cacheMap(255)
  {
	const char * pEnvCache = getenv( "SAL_GRAPHITE_CACHE_SIZE" );
	if (pEnvCache != NULL)
	{
		int envCacheSize = atoi(pEnvCache);
		if (envCacheSize <= 0)
			m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE;
		else
		{
			m_nSegCacheSize = envCacheSize;
		}
	}
	else
	{
		m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE;
	}
  };
  ~GraphiteCacheHandler()
  {
    GraphiteCacheMap::iterator i = m_cacheMap.begin();
    while (i != m_cacheMap.end())
    {
      GraphiteSegmentCache *r = i->second;
      delete r;
      ++i;
    }
    m_cacheMap.clear();
  };

  static GraphiteCacheHandler instance;

  GraphiteSegmentCache * getCache(sal_Int32 & fontHash)
  {
    if (m_cacheMap.count(fontHash) > 0)
    {
      return m_cacheMap.find(fontHash)->second;
    }
    GraphiteSegmentCache *pCache = new GraphiteSegmentCache(m_nSegCacheSize);
    m_cacheMap[fontHash] = pCache;
    return pCache;
  }
private:
  GraphiteCacheMap m_cacheMap;
  sal_uInt32 m_nSegCacheSize;
};

#endif

