function CLibrary(debugMode)
{
  var thisPtr = this;
  this.debugMode = debugMode;

  // ERRORS
  this.errorMessage =
  {
    HTMLElementIsNotFound: "HTML Element is not found: ",
    ObjectPropertyIsAbsent: "Object property is absent!"
  }

  this.isDebugMode = function()
  {
    return thisPtr.debugMode;
  }

  this.debugMessage = function(messageText)
  {
    if (thisPtr.debugMode)
    {
      alert(messageText);
    }
  }

  this.getElementByIdEx = function(id)
  {
    if (document.getElementById(id))
    {
      return document.getElementById(id);
    }
    else
    {
      thisPtr.debugMessage(thisPtr.errorMessage.HTMLElementIsNotFound + id);
      return false;
    }
  }

  this.createElementEx = function(elementType)
  {
    var result;

    result = document.createElement(elementType);

    return result;
  }

  this.createElementInPopup = function(popup, elementType)
  {
    var result;

    result = popup.document.createElement(elementType);

    return result;
  }


  this.parseQueryString = function(url)
  {
    var objParams       = new Object();
    var arrParamsPairs  = new Array();
        
    var posStart        = url.indexOf("?");

    if (posStart < url.length - 1 && posStart >= 0)
    {
      queryStr = url.substr(posStart + 1, url.length);
      arrParamPairs = queryStr.split("&");
      var tmpArr;
      for (var i = 0; i < arrParamPairs.length; i++)
      {
        tmpArr = arrParamPairs[i].split("=");
        objParams[tmpArr[0]] = tmpArr[1];
      }
      objParams["__length"] = arrParamsPairs.length;
    }

    return objParams;
  }

  this.findInResource = function(resource, element, value)
  {
    var len = resource.length;

    if (len > 0)
    {
      for (var i = 0; i < len; i++)
      {
        if (resource[i][element] == value)
        {
          return i;
        }
      }
    }
    return null;
  }


  this.isInObject = function(id, source)
  {
     for (var i in source)
     {
        if (source[i] == id)
        {
           return true;
        }
     }
     thisPtr.debugMessage(thisPtr.errorMessage.ObjectPropertyIsAbsent);
     return false;
  }


  this.sortByYear = function(resource)
  {
    var len;
    var tmp;   

    len = resource.length;

    for (var i = 0; i < len; i++)
    {
      for (var j = 0; j < len; j++)
      {
        if (resource[i].Year > resource[j].Year)
        {
          tmp = resource[i];
          resource[i] = resource[j];
          resource[j] = tmp;
        }
      }
    }
  }

  this.createIndex = function(resource)
  {
    var len = resource.length;

    if (len > 0)
    {
      for (var i = 0; i < len; i++)
      {
        if (resource[i].Idx != DEF_ILLUSTRATION_INDEX)
        {
          resource[i].Idx = i + DEF_ILLUSTRATION_INDEX + 1;
        }
      }
    }
  }

  this.createIndexByCategory = function(resource, categories)
  {
    var len = resource.length;
    var count;

    if (len > 0)
    {
      for (var j in categories)
      {
        count = 1;
        for (var i = 0; i < len; i++)
        {
          if (resource[i].Category == categories[j])
          {
            resource[i].Num = count;
            count++;
          }
        }
      }
    }
  }

  this.renderContent = function(resource)
  {
    var len;
    var node;

    if (resource == null)
    {
      return;
    }

    len = resource.length;
        
    for (var i = 0; i < len; i++)
    {
      var name;
      var node; 
 
      name = resource[i].Id;
      node = thisPtr.getElementByIdEx(name);

      if (!node)
      {
        return false;
      }

      if (resource[i].IsImage)
      {
        thisPtr.renderImage(node, resource[i]);
      }

      if (resource[i].IsLink != false)
      {
        thisPtr.renderLink(node, resource[i], resource[i].IsLink);
      }

      if (!resource[i].IsImage &&
          !resource[i].IsLink)
      {
        thisPtr.renderText(node, resource[i]);
      }
    }
  }

  this.renderText = function(node, data)
  {
    node.innerHTML = data.Text[thisPtr.getLanguage()];
  }

  this.renderImage = function(node, data)
  {
    node.src = DEF_PATH_IMAGES + data.Resource[thisPtr.getLanguage()];
    var str = thisPtr.formatString(data.Text[thisPtr.getLanguage()]);
    node.alt = str;
  }

  this.renderLink = function(node, data, flag)
  {
    node.href = thisPtr.createFullURL(data.Resource);
    var str = thisPtr.formatString(data.Text[thisPtr.getLanguage()]);
    node.title = str;

    if (flag == null)
    {
      node.innerHTML = str;
    }
  }

  this.createLink = function(data, style)
  {
    var oLink;
    oLink = thisPtr.createElementEx("a");
    oLink.href = thisPtr.createFullURL(data);
    oLink.title = data.Text[thisPtr.getLanguage()];
    oLink.innerHTML = data.Text[thisPtr.getLanguage()];
    oLink.className = style;
    oLink.onfocus = function() { this.blur(); };

    return oLink;
  }

  this.formatString = function(data)
  {
    var res = data;

    res = res.replace("&laquo;", "\"");
    res = res.replace("&raquo;", "\"");
  
    return res;
  }


  this.reduceString = function(str, maxLen)
  {
    var etcString = "...";
    var etcStringLen = 3;

    if (str.length > maxLen)
    {
      if (maxLen > 2)
      {
          str = str.substr(0, maxLen - 1 - etcStringLen) + etcString;
      }
      else
      {
          str = str.substr(0, maxLen - 1) + etcString;
      }
    }
    return str;
  }

  this.createURL = function(pageId, params, langId)
  {
    var newURL;
    var baseURL;

    baseURL = DEF_BASE_URL;

    if (pageId == null)
    {
      pageId = g_currentPageId;
    }

    if (langId == null)
    {
      langId = g_language;
    }

    newURL = baseURL + "?pageId=" + pageId + params + "&langId=" + langId;

    return encodeURI(newURL);
  }

  this.createFullURL = function(data)
  {
    var fullURL;

    var pictureIndex;
    var pictureFile;
    var pictureCategory;
    var params;

    if (data.ParamId != -1)
    {
      if (data.ParamId)
      {
        if (data.ParamId.Idx)
        {
          pictureIndex = data.ParamId.Idx;
        }
        else
        {
          pictureIndex    = null;
        }

        if (data.ParamId.Img)
        {
          pictureFile = data.ParamId.Img;
        }
        else
        {
          pictureFile     = null;
        }

        if (data.ParamId.Cgr)
        {
          pictureCategory = data.ParamId.Cgr;
        }
        else
        {
          pictureCategory = null;
        }
      }

      params = thisPtr.createParams(pictureIndex, pictureFile, pictureCategory);
    }
    else
    {
      params = "";
    }

    fullURL = thisPtr.createURL(data.PageId, params, data.LangId);

    return fullURL;
  }

  this.isEmpty = function(value)
  {
    if (value == null || value == "" || value == "undefined")
    {
      return true;
    }

    return false;
  }

  this.createParams = function(pictureIndex, pictureName, pictureCategory)
  {
    var res = "";

    if (!thisPtr.isEmpty(pictureIndex))
    {
      res += "&idx=" + pictureIndex;
    }
    else if (!thisPtr.isEmpty(g_params.idx))
    {
      res += "&idx=" + g_params.idx;
    }   

    if (!thisPtr.isEmpty(pictureName))
    {
      res += "&img=" + pictureName;
    }
    else if (!thisPtr.isEmpty(g_params.img))
    {
      res += "&img=" + g_params.img;
    }

    if (!thisPtr.isEmpty(pictureCategory))
    {
      res += "&cgr=" + pictureCategory;
    }
    else if (!thisPtr.isEmpty(g_params.cgr))
    {
      res += "&cgr=" + g_params.cgr;
    }

    return res;
  }

  this.getLanguage = function()
  {
    if (g_language == g_enumLanguages.Eng)
    {
      return "Eng";
    }

    if (g_language == g_enumLanguages.Rus)
    {
      return "Rus";
    }
  }

  this.getElementCSSList = function(name)
  {
    var res = "";

    node = document.getElementById(name);

    var count = 0;

    for (var i in node.style)
    {
      res += " " + node.style[i];
      count++
      
      if (count == 10)
      {
        count = 0;
        res += "\n";
      }
    }

    alert(res);
  }


  this.renderPage = function(outFile, headerFile, footerFile, pageId)
  {
    if (!thisPtr.debugMode)
    {
      return;
    }

    var element;
    var fileSystemObject;
    var stream;

    var headerContent;
    var content;
    var footerContent;

    element = thisPtr.getElementByIdEx(pageId);

    fileSystemObject = new ActiveXObject("Scripting.FileSystemObject");

    headerContent = thisPtr.readFile(fileSystemObject, DEF_BASE_PATH + headerFile);
    footerContent = thisPtr.readFile(fileSystemObject, DEF_BASE_PATH + footerFile);
    content = headerContent + "\x0D" + "\x0A" + element.innerHTML + footerContent;

    stream = fileSystemObject.OpenTextFile(DEF_BASE_PATH + outFile, g_enumFileOperations.forWriting);

    stream.Write(content);
    stream.Close();
  }

  this.readFile = function(fileSystemObject, fileName)
  {
    var content = "";
    var stream;
    var file;

    stream = fileSystemObject.OpenTextFile(fileName, g_enumFileOperations.forReading);
    file = fileSystemObject.GetFile(fileName);

    if (file.size > 0)
    {
      content = stream.ReadAll();
    }
    stream.Close();

    return content;
  }


  this.cleanNode = function(dest)
  {
    while (dest.firstChild)
    {
      dest.removeChild(dest.firstChild);
    }
  }
}