
// returns the post content element ID by the message ID
function messageContainerIdFromPosition( messageId )
{
  return "msg"+messageId;
}

// loads the resources set with ID, given, content into the document content
// the message ID is the optional parameter, saying that this message is
// the message, which requires this resources set
function updateResourcesSetContent( resourcesSetId, messageId )
{
  // checking the resources set's update time and, if it is bigger, then
  // the last update time for this page - updating this resources set
  if ( resourcesSetsLastUpdateTime[resourcesSetId] && ( resourcesSetsLastUpdateTime[resourcesSetId] >= resourcesSetsLastModificationTime[resourcesSetId] ) )
    return;
  
  // storing the resources set's last modification time as the last update time
  resourcesSetsLastUpdateTime[resourcesSetId] = resourcesSetsLastModificationTime[resourcesSetId];
  
  // updating the resources set content
  sendUrlResponseXmlToFunction
  ( 
    updateResourcesSetContentRequestUrl + resourcesSetId,
    function( response )
    {
      // an empty response comes from time to time. Retrying then
      if ( !response )
      {
        updateResourcesSetContent( resourcesSetId );
        return;
      };
      if ( response == RESPONSE_RESOURCE_NOT_FOUND )
      {
        if ( USER_RIGHTS_MODERATE )
        {
          if ( confirm( "Глючный набор ресурсов: " + resourcesSetId + ", удалить?" ) )
          {
            for ( var messageId in documentMap )
              if ( documentMap[messageId] == resourcesSetId )
                removeMessageWithId( messageId );
          };
        };
        for ( var messageId in documentMap )
          if ( documentMap[messageId] == resourcesSetId )
            documentContent[messageId] = RESPONSE_RESOURCE_NOT_FOUND;
        // updating the page content
        redrawDocument();
        return;
      }
      else if ( response == RESPONSE_FORBIDDEN )
      {
        for ( var messageId in documentMap )
          if ( documentMap[messageId] == resourcesSetId )
            documentContent[messageId] = RESPONSE_RESOURCE_NOT_FOUND;
        // updating the page content
        redrawDocument();
        return;
      };

      var messages = response.getElementsByTagName("resource");
      if ( messages.length > 0 )
      {
        for ( var messageI = 0; messageI < messages.length; messageI++ )
        {
          //if ( !( messages[messageI].getAttribute ) )
          //  continue;
          var messageId = messages[messageI].getAttribute( "id" );
          if ( !messageId )
            continue;
          if ( !(documentContent[messageId]) )
            documentContent[messageId] = new Array();

          if ( messages[messageI].getElementsByTagName("title").length > 0 )
            documentContent[messageId]["name"] = messages[messageI].getElementsByTagName("title")[0].firstChild.nodeValue;
          // saving authors IDs
          if ( !documentContent[messageId]["authors"] )
            documentContent[messageId]["authors"] = new Array();
          if ( messages[messageI].getElementsByTagName("authors").length > 0 )
          {
            var authors = messages[messageI].getElementsByTagName("authors")[0].getElementsByTagName("item");
            if ( authors.length > 0 )
              for ( var authorI = 0; authorI < authors.length; authorI++ )
                documentContent[messageId]["authors"][authors[authorI].firstChild.nodeValue] = true;
          };
          // converting the UNIX time into the time string
          var date = new Date();
          if ( messages[messageI].getElementsByTagName("time").length > 0 )
          {
            if ( messages[messageI].getElementsByTagName("time")[0].getElementsByTagName("lastModification").length > 0 )
              date.setTime( 1000*messages[messageI].getElementsByTagName("time")[0].getElementsByTagName("lastModification")[0].firstChild.nodeValue );
            else if ( messages[messageI].getElementsByTagName("time")[0].getElementsByTagName("creation").length > 0 )
              date.setTime( 1000*messages[messageI].getElementsByTagName("time")[0].getElementsByTagName("creation")[0].firstChild.nodeValue );
            documentContent[messageId]["time"] = date.toLocaleDateString() + " " + date.toLocaleTimeString();
          };
          documentContent[messageId]["plaintext"] = "";
          if ( messages[messageI].getElementsByTagName("text").length > 0 )
          {
            var textParts = messages[messageI].getElementsByTagName("text")[0].childNodes;
            if ( textParts.length > 0 )
              for ( textPartI = 0; textPartI < textParts.length; textPartI++  )
                if ( textParts[textPartI].nodeValue )
                  documentContent[messageId]["plaintext"] += textParts[textPartI].nodeValue;
            // nicing-up the content
            documentContent[messageId]["text"] = prepareText( documentContent[messageId]["plaintext"] );
          };
        };
      }
      else 
        if ( USER_RIGHTS_MODERATE )
          if ( confirm( "Глючный набор ресурсов: " + resourcesSetId + ", удалить?" ) )
          {
            for ( var messageId in documentMap )
              if ( documentMap[messageId] == resourcesSetId )
                removeMessageWithId( messageId );
          };
      // updating the page content
      redrawDocument();
    }
  );
}

// generates the document content draws it
function redrawDocument()
{
  // finding the element
  var element = obtainElementById( "posts" );
  // checking
  if ( !element ) return;
  
  // the visible document part content
  var content = "<table width='100%'>\n";
  
  // the visible document part dimensions
  if ( numberOfPages < 0 ) return;
  var firstMessageNumber = 0;
  if ( pageNumber == DEFAULT_PAGE_NUMBER )
    firstMessageNumber = Math.max( 0, numberOfResources - resourcesPerPage );
  else
    firstMessageNumber = Math.min( numberOfResources - 1, max( 0, pageNumber * resourcesPerPage ) );
  var lastMessageNumber = Math.min( numberOfResources - 1, firstMessageNumber + resourcesPerPage - 1 );
  
  // generating the navigation links
  var links = "";
  for ( var i = 0; i < numberOfPages; i++ )
    links += "&nbsp;" + ( i == pageNumber ? "&gt;" : "" ) + "<a href='"+URL_PREFIX+DOCUMENT_PATH_STRING+"?"+PARAM_PAGE_NUMBER+"=" + i + "'>" + (i+1) + "</a>" + ( i == pageNumber ? "&lt;" : "" ) + " \n";
    
  // adding links section
  content += "<tr><td style='padding:20px'><h3 style='display:inline'><a href='"+URL_PREFIX+DOCUMENT_PATH_STRING+"'>Последние сообщения</a> Страницы: " + links + "</h3> <small>(Ctrl&nbsp;+&nbsp;&larr;&nbsp;&mdash;&nbsp;предыдущая, Ctrl&nbsp;+&nbsp;&rarr;&nbsp;&mdash;&nbsp;следующая)</small></td><td style='text-align:right'><a href='"+URL_PREFIX+DOCUMENT_PATH_STRING+"?"+PARAM_FUNCTION+"="+PARAM_FUNCTION_RSS+"'><img style='border:none' src='"+MODULE_PATH+"rss.gif' width='14' height='14' /></a></td></tr>\n";
  
  // generating the messages
  var messageNumber = -1;
  var documentNotLoadedFully = false;
  for ( var messageId in documentMap )
  {
    // skipping unwanted messages
    messageNumber++;
    if ( messageNumber < firstMessageNumber || messageNumber > lastMessageNumber )
      continue;

    if ( documentContent[messageId] && documentContent[messageId] != RESPONSE_RESOURCE_NOT_FOUND )
    {
      content += "<tr><td style='padding-top:20px'><h2 style='display:inline;'>"+documentContent[messageId]['name']+"</h2>&nbsp; <small>(" + documentContent[messageId]['time'] + ")</small></td>\n<td align='right' valign='bottom' style='width:80px'>";
      if ( documentContent[messageId]["authors"][USER_ID] )
        if ( USER_ID != DEFAULT_USER_ID )
          content += "<img width='20' height='20' onclick='javascript: prepareCommentBoxForEditFunctionality( \""+messageId+"\" )' src='"+MODULE_PATH+"edit.gif' onmouseover='javascript: placeElementWithContentOnTopFromMe( this, \"hintconstrain\", \"hintcontent\", \"Редактировать сообщение.<br />Для&nbsp;вызова этой функции можно также сделать двойной щелчёк на&nbsp;тексте.\", 0, 0, hintHidingDelay );' onmouseout='javascript: startHidingLastElement(\"hintconstrain\");'/>";
      if ( !documentContent[messageId]["authors"][USER_ID] )
        if ( USER_RIGHTS_MODERATE )
          content += "<img width='20' height='20' onclick='javascript: banUserByMessageWithId( \""+messageId+"\" )' src='"+MODULE_PATH+"ban.gif' onmouseover='javascript: placeElementWithContentOnTopFromMe( this, \"hintconstrain\", \"hintcontent\", \"Удалить сообщения этого пользователя за&nbsp;последние сутки и&nbsp;добавить штрафное очко на&nbsp;его IP-адрес.\", 0, 0, hintHidingDelay );' onmouseout='javascript: startHidingLastElement(\"hintconstrain\");'/>";
      if ( USER_RIGHTS_MODERATE )
        content += "<img width='20' height='20' onclick='javascript: removeMessageWithId( \""+messageId+"\" )' src='"+MODULE_PATH+"moderate.gif' onmouseover='javascript: placeElementWithContentOnTopFromMe( this, \"hintconstrain\", \"hintcontent\", \"Удалить сообщение.\", 0, 0, hintHidingDelay );' onmouseout='javascript: startHidingLastElement(\"hintconstrain\");'/>";
      content += "</td></tr>\n";
      
      content += "<tr><td colspan='2'><div ";
      if ( documentContent[messageId]["authors"][USER_ID] )
        content += ( USER_ID != DEFAULT_USER_ID ? "ondblclick='javascript: if ( documentContent[ \""+messageId+"\" ][\"authors\"][\""+USER_ID+"\"] ) prepareCommentBoxForEditFunctionality( \""+messageId+"\" )'" : "" );
      //else
      //  content += "<tr><td";
      content += "id='"+messageContainerIdFromPosition( messageId )+"' class='resourcetext'  >"+documentContent[messageId]['text']+"</div></td></tr>\n";
    }
    else if ( documentContent[messageId] != RESPONSE_RESOURCE_NOT_FOUND )
    {
      updateResourcesSetContent( documentMap[messageId], messageId );
      documentNotLoadedFully = true;
      //return;
    };
  };
  // returning to prevent the unformed document redrawing
  if ( documentNotLoadedFully ) 
    return;
    
  content += "</table>\n";
  
  if ( element.innerHTML != content )
  {
    // updating the content
    element.innerHTML = content;
    
    // setting the comment box visibility and scrolling to the bottom
    // to make the document look smooth
    commentBox = obtainElementById( "commentbox" );
    if ( commentBox )
    {
      // allowing or the comments posting only if the last message is shown
      if ( pageNumber == DEFAULT_PAGE_NUMBER || 
           pageNumber == numberOfPages - 1 )
      {
        if ( commentBox.style.display == "none" )
          commentBox.style.display = "block";
        // scrolling to the bottom, if the text field is highlighted
        //if ( pageNumber == <?php echo DEFAULT_PAGE_NUMBER?> )
          //window.scrollBy( 0, 32000 );
      }
      else
        commentBox.style.display = "none";
    };
    
    // refreshing the window
    refreshMainElementsPositions();
  };
}

// forms the request to the script
// to remove the message with the ID, given
function removeMessageWithId( messageId )
{
  if ( !confirm( "Удалить сообщение "+messageId+"?" ) )
    return;

  // building the list of params
  var params = new Array();
  params[PARAM_MESSAGE_ID] = messageId;
  params[PARAM_DOCUMENT_PATH_STRING] = DOCUMENT_PATH_STRING;
  
  // removing the resource from the document
  sendUrlResponseTextToFunction
  ( 
    removeMessageTextRequestUrl,
    function( response )
    {
      if ( response == RESPONSE_REQUEST_PROCEEDED_SUCCESSFULLY )
        // updating the document
        updateCallback();
      else
        alert( response );
    },
    params
  );
}

// forms the request to the script
// to ban the user, who wrote the message with the ID, given
function banUserByMessageWithId( messageId )
{
  if ( !confirm( "Забанить?" ) )
    return;

  // building the list of params
  var params = new Array();
  params[PARAM_MESSAGE_ID] = messageId;
  params[PARAM_DOCUMENT_PATH_STRING] = DOCUMENT_PATH_STRING;
  
  // removing the resource from the document
  sendUrlResponseTextToFunction
  ( 
    banByMessageTextRequestUrl,
    function( response )
    {
      if ( response == RESPONSE_REQUEST_PROCEEDED_SUCCESSFULLY )
        // updating the document
        updateCallback();
      else
        alert( response );
    },
    params
  );
}

// sends the request to add the message
function sendMessage()
{
  /*
  if ( USER_ID == DEFAULT_USER_ID )
    if ( !confirm( "Вы не авторизовались. Вы всё равно хотите отправить сообщение? (лучше бы войти на сайт сначала)" ) )
      return;
    */

  var name = obtainElementById( 'namefield' ).value;
  var email = obtainElementById( 'emailfield' ).value;
  var phone = obtainElementById( 'phonefield' ).value;
  var text = decodeHtmlEntities( obtainElementById( 'textfield' ).value );
  //var name = obtainElementById( 'namefield' ).value;
  
  // checking to have something to do
  if ( name == "" )
  {
    alert( "Заполните пожалуйста Ваше имя" );
    return;
  };
    
  if ( phone == "" && email == "" )
  {
    alert( "Заполните пожалуйста Ваш телефон или хотябы e-mail" );
    return;
  };
    
  // disabling the text field
  obtainElementById( 'namefield' ).disabled = true;
  obtainElementById( 'phonefield' ).disabled = true;
  obtainElementById( 'emailfield' ).disabled = true;
  obtainElementById( 'textfield' ).disabled = true;
  
  // building the list of params
  var params = new Array();
  params[PARAM_MESSAGE_NAME] = name;
  params[PARAM_MESSAGE_PHONE] = phone;
  params[PARAM_MESSAGE_EMAIL] = email;
  params[PARAM_MESSAGE_TEXT] = text;
  params[PARAM_DOCUMENT_PATH_STRING] = DOCUMENT_PATH_STRING;
  
  // adding the resource to the document
  sendUrlResponseTextToFunction
  ( 
    addMessageTextRequestUrl, 
    function( response )
    {
      if ( response == RESPONSE_REQUEST_PROCEEDED_SUCCESSFULLY )
      {
        alert( "Спасибо! Мы скоро с Вами свяжемся!" );

        // clearing the text field
        obtainElementById( 'namefield' ).value = "";
        obtainElementById( 'phonefield' ).value = "";
        obtainElementById( 'emailfield' ).value = "";
        obtainElementById( 'textfield' ).value = "";
        // moving to the default (tracking last messages) page
        pageNumber = DEFAULT_PAGE_NUMBER;
        // updating the document
        updateCallback();
        // enabling back the text field
        obtainElementById( 'namefield' ).disabled = false;
        obtainElementById( 'phonefield' ).disabled = false;
        obtainElementById( 'emailfield' ).disabled = false;
        obtainElementById( 'textfield' ).disabled = false;
        // focusing it to pretty-up
        //obtainElementById( 'namefield' ).focus();
        obtainElementById( 'namefield' ).blur();
        obtainElementById( 'namefield' ).focus();        
      }
      else
        alert( response );
    },
    params
  );
}

// sends the request to change the message content
function sendEditMessage( messageId )
{
  var name = obtainElementById( 'namefield' ).value;
  var email = obtainElementById( 'emailfield' ).value;
  var phone = obtainElementById( 'phonefield' ).value;
  var text = decodeHtmlEntities( obtainElementById( 'textfield' ).value );
  //var name = obtainElementById( 'namefield' ).value;
  
  // checking to have something to do
  if ( name == "" )
  {
    alert( "Заполните пожалуйста Ваше имя" );
    return;
  };
    
  if ( phone == "" && email == "" )
  {
    alert( "Заполните пожалуйста Ваш телефон или хотябы e-mail" );
    return;
  };
    
  // disabling the text field
  obtainElementById( 'namefield' ).disabled = true;
  obtainElementById( 'phonefield' ).disabled = true;
  obtainElementById( 'emailfield' ).disabled = true;
  obtainElementById( 'textfield' ).disabled = true;
  
  // building the list of params
  var params = new Array();
  params[PARAM_MESSAGE_NAME] = name;
  params[PARAM_MESSAGE_PHONE] = phone;
  params[PARAM_MESSAGE_EMAIL] = email;
  params[PARAM_MESSAGE_TEXT] = text;
  params[PARAM_MESSAGE_ID] = messageId;
  params[PARAM_DOCUMENT_PATH_STRING] = DOCUMENT_PATH_STRING;
  
  // adding the resource to the document
  sendUrlResponseTextToFunction
  ( 
    editMessageTextRequestUrl, 
    function( response )
    {
      if ( response == RESPONSE_REQUEST_PROCEEDED_SUCCESSFULLY )
      {
        // clearing the text field
        obtainElementById( 'textfield' ).value = "";
        // moving to the default (tracking last messages) page
        pageNumber = DEFAULT_PAGE_NUMBER;
        // updating the document
        updateCallback();
        // enabling back the text field
        //obtainElementById( 'textfield' ).disabled = false;
        // focusing it to pretty-up
        //obtainElementById( 'namefield' ).focus();
        obtainElementById( 'textfield' ).blur();
        obtainElementById( 'textfield' ).focus();
      }
      else
        alert( response );
    },
    params
  );
}

function prepareCommentBoxForEditFunctionality( messageId )
{
  obtainElementById( 'commentboxheader' ).innerHTML = "Изменить сообщение";
  obtainElementById( 'submitbutton' ).value = "Заменить (Ctrl+Enter)";
  obtainElementById( 'submitbutton' ).onclick = function(){sendEditMessage(messageId);prepareCommentBoxForDefaultFunctionality();};
  obtainElementById( 'cancelbuttoncontainer' ).style.display = "block";
  if ( documentContent[messageId] )
    obtainElementById( 'textfield' ).value = decodeHtmlEntities( documentContent[messageId]['plaintext'] );
  obtainElementById( 'textfield' ).disabled = false;
  //obtainElementById( 'textfield' ).focus();
}

function prepareCommentBoxForDefaultFunctionality()
{
  obtainElementById( 'commentboxheader' ).innerHTML = "Закажите наши товары";
  obtainElementById( 'submitbutton' ).value = "Отправить (Ctrl+Enter)";
  obtainElementById( 'submitbutton' ).onclick = function(){sendMessage();};
  obtainElementById( 'textfield' ).value = defaultTextFieldValue;
  obtainElementById( 'cancelbuttoncontainer' ).style.display = "none";
  setElementHeightById( 'textfield', 250 );
  obtainElementById( 'textfield' ).disabled = false;
  //obtainElementById( 'textfield' ).focus();
}

// moves to the previous page on Ctrl+<-
// moves to the next page on Ctrl+->
// sends the message on Ctrl+Enter
function globalKeysTreatment( event )
{
  event = (event) ? event : window.event;
  if ( event.ctrlKey && !( event.shiftKey || event.altKey ) ) 
    switch ( event.keyCode )
    {
      // previous page
      case 37:
        // protecting the text field data from loosing
        textField = obtainElementById( "textfield" );
        if ( ( textField && ( textField.value == "" || textField.value == defaultTextFieldValue ) ) || textField == null )
        {
          if ( pageNumber != 0 )
          {
            if ( pageNumber != DEFAULT_PAGE_NUMBER )
              pageNumber = Math.max( 0, pageNumber - 1 );
            else
              pageNumber = Math.max( 0, numberOfPages - 1 );
            // scrolling to the top to make movement smooth
            window.scroll( 0, 0 );
            // redrawing the document
            redrawDocument();
          };
        };
        break;
      // next page
      case 39:
        // protecting the text field data from loosing
        textField = obtainElementById( "textfield" );
        if ( ( textField && ( textField.value == "" || textField.value == defaultTextFieldValue ) ) || textField == null )
        {
          if ( pageNumber != DEFAULT_PAGE_NUMBER )
          {
            pageNumber = Math.min( numberOfPages, pageNumber + 1 );
            if ( pageNumber == numberOfPages )
              pageNumber = DEFAULT_PAGE_NUMBER;
            // scrolling to the top to make movement smooth
            window.scroll( 0, 0 );
            // redrawing the document
            redrawDocument();
          };
        };
        break;
      // submit
      case 13:
        var submitButton = obtainElementById( 'submitbutton' );
        if ( submitButton )
          submitButton.click();
        break;
    };
}
