#!/usr/bin/perl
# ----------------------------------------------------------------------------
# This software is Copyright (C) 2007, All Rights Reserved
# ----------------------------------------------------------------------------
# This program is protected by local and international copyright laws. Any
# use of this program is subject to the the terms of the license agreement
# included as part of this distribution archive. Any other uses are strictly
# prohibited without the written permission of the Vendor and all
# other rights are reserved.
# -----------------------------------------------------------------------------
# Warning : Modifying this program violates your license agreement!
# -----------------------------------------------------------------------------

package IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory;

# load modules
use strict;

use IT::Globals;

use vars qw($MAXIMUM_CATEGORIES_ALLOWED_PER_ARTICLE);

# ------------------------------------------------------------------------------
# Function    : createFieldHtml
# Description :
# Usage       : &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::createFieldHtml($tableNameWithPrefix, $fieldName, $placeholders)
# ------------------------------------------------------------------------------

sub createFieldHtml {
  my $articleTableName    = shift || die "no tablename specified!";
  my $fieldName           = shift;
  my $placeholders        = shift;
  my $fieldValue         = $placeholders->{$fieldName};
  my $template            = "admin/menus/_customEditFields.html";

  # get listStruct with category numbers (from all category fields) and maxRows (total number of category fields)
  my($listStruct, $maxRows) = &_getListStructForCategoryNums($articleTableName, $placeholders);

  # define placeholders
  $placeholders                                = { %{$placeholders} };  # copy hash values so we don't modify global
  $placeholders->{'articleEditorCategoryList'} = &_createCategoryList();
  $placeholders->{'_hiddenFields'}             = &IT::DhtmlFieldLists::createHiddenRowFields($fieldName, $listStruct);
  $placeholders->{'_highestRecordNumber'}      = $listStruct->{'config'}{'highest_record_number'};
  $placeholders->{'_maxRowsAllowed'}           = $maxRows;

  # generate field html
  my $html = &templateCell($template, 'articleEditorCategoryList', $placeholders);

  return $html;

}

# ------------------------------------------------------------------------------
# Function    : _getCategoryListStructAndMaxRows
# Description :
# Usage       : my($listStruct, $maxRows) = &_getCategoryListStructAndMaxRows($tableName, $placeholders);
# ------------------------------------------------------------------------------

sub _getListStructForCategoryNums {
  my $articleTableName = shift || die "no tablename specified!";
  my $placeholders     = shift || die "no placeholders specified!";

  # get category numbers and field count
  my @categoryNums;
  my $categoryFieldCount    = 0;
  my $allCategoryFieldnames = &getArticleCategoryFieldnames('all');
  foreach my $categoryFieldname (@$allCategoryFieldnames) {
    $categoryFieldCount++;
    my $categoryNum = $placeholders->{ $categoryFieldname };
    if ($categoryNum) {
      push @categoryNums, $placeholders->{ $categoryFieldname };
    }
  }

  # create list struct
  my $rowCounter   = 0;
  my $listStruct   = {
    'rows'   => {},
    'config' => {},
  };
  foreach my $categoryNum (@categoryNums) {
    $rowCounter++;
    $listStruct->{'rows'}{$rowCounter}{'_num'}        = $rowCounter;
    $listStruct->{'rows'}{$rowCounter}{'_order'}      = $rowCounter;
    $listStruct->{'rows'}{$rowCounter}{'_erased'}     = 0;
    $listStruct->{'rows'}{$rowCounter}{'categoryNum'} = $categoryNum;
  }
  $listStruct->{'config'}{'highest_record_number'}    = $rowCounter;


  # return values
  return($listStruct, $categoryFieldCount);
}

# ------------------------------------------------------------------------------
# Function    : _createCategoryList
# Description :
# Usage       : my $categoryList = &_createCategoryList();
# ------------------------------------------------------------------------------

sub _createCategoryList {
  my $categoryList;
  my $template = "admin/menus/_customEditFields.html";

  # load category data
  my $sortedRecords = &IT::ArtMan::CustomMenus::Category::getSortedFilteredCategoryArray({
                        showLockedCategories        => 0,
                        limitByCategoryAccessRights => 1,
                      });

  # generate category list
  local $IT::Template::OUTPUT_ID_COMMENTS = 0;    # temporarily disable template debug mode tags in output
  foreach my $category (@$sortedRecords) {
    my $num = $category->{'num'};
    my $cellPlaceholders = {};
    $cellPlaceholders->{'_breadcrumbText'} = &IT::ArtMan::CustomMenus::Category::generateTextBreadcrumb($num);
    $cellPlaceholders->{'_optionValue'}    = $num;
    $categoryList .= &templateCell($template, 'articleEditorCategoryRow', $cellPlaceholders);
  }

  #
  return $categoryList;
}

# ------------------------------------------------------------------------------
# Function    : getRecordFieldFromFormInput
# Description :
# Usage       : my $recordFieldValue = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getRecordFieldFromFormInput($fieldName)
# ------------------------------------------------------------------------------

sub getRecordFieldFromFormInput {
  my $specifiedFieldName = shift || die "no fieldname specified!";

  # get array of article category fields
  my $allCategoryFieldnames     = &getArticleCategoryFieldnames('all');
  my $primaryCategoryFieldnames = &getArticleCategoryFieldnames('primary');
  my $primaryCategoryFieldname  = $primaryCategoryFieldnames->[0] || die "No primary category field defined!";

  # get array of category nums from form input
  my %selectedCategoryNums;
  my @categoryNums;
  my $listStruct = &IT::DhtmlFieldLists::getListStructFromFormData($primaryCategoryFieldname);
  my $byRowOrder = sub { $listStruct->{'rows'}{$a}{'_order'} <=> $listStruct->{'rows'}{$b}{'_order'} };
  foreach my $rowNum (sort $byRowOrder keys %{$listStruct->{'rows'}}) {
    my $categoryNum = $listStruct->{'rows'}{$rowNum}{'categoryNum'};
    if ($categoryNum && !$selectedCategoryNums{$categoryNum}) {
      push @categoryNums, $categoryNum;
      $selectedCategoryNums{$categoryNum} = 1;  # don't count same category more than once
    }
  }

  # create hash of category fieldnames to values
  my %categoryFieldNameToValue;
  for my $index (0..$#$allCategoryFieldnames) {
    my $fieldName  = $allCategoryFieldnames->[$index];
    my $fieldValue = $categoryNums[$index];
    $categoryFieldNameToValue{ $fieldName } = $fieldValue;
  };

  # get category value for for this field index
  my $recordValue = $categoryFieldNameToValue{ $specifiedFieldName };

  #
  return $recordValue;
}

# ------------------------------------------------------------------------------
# Function    : getPlaceholderFromRecordField
# Description :
# Usage       : my $placeholderValue = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getPlaceholderFromRecordField($recordFieldValue)
# ------------------------------------------------------------------------------

sub getPlaceholderFromRecordField {
  my $fieldValue = shift;
  my $record     = shift;

  # define placeholder
  my $placeholderValue = $fieldValue;

  return $placeholderValue;
}

# ------------------------------------------------------------------------------
# Function    : errorCheckingForUserInput
# Description :
# Usage       : &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::errorCheckingForUserInput()
# ------------------------------------------------------------------------------

sub errorCheckingForUserInput {
  my($fieldLabelOrName, $fieldFormInput, $fieldName, $tableName, $recordNum) = @_;
  my $error;

  # at least one category must be defined!
  my $fieldValue = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getRecordFieldFromFormInput($fieldName);
  unless ($fieldValue) {
    $error .= "You must select a category!" ;
  }

  # Category Access Rights are enforced in IT::ArtMan::CustomMenus::Article.pm
  # since we need to check them on edit, confirmErase, erase, and save

  # return errors
  if ($error) { return $error; }
  else        { return; } # return empty list so nothing is added to errors array
}

# ------------------------------------------------------------------------------
# Function    : errorCheckingForFieldEditor
# Description :
# Usage       : &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::errorCheckingForFieldEditor($customFieldAttributes)
# ------------------------------------------------------------------------------

sub errorCheckingForFieldEditor {
  my($customFieldAttributes) = @_;
  my @errors;

  # don't allow user to change field name
  if ($FORM->{'newFieldName'} ne 'categoryNum') { push @errors, "This is a required field and must be named 'categoryNum'."; }

  # don't allow attributes: hidden, not editable
  if ($FORM->{'appHiddenField'}) { push @errors, "This is a required field and cannot be made hidden."; }
  if ($FORM->{'appDisplayOnly'}) { push @errors, "This is a required field and cannot be made not editable."; }

  # require field type: int
  my %validDbFieldTypes      = map { $_ => 1 } qw(int);
  my $isValidDbFieldType     = $validDbFieldTypes{ $FORM->{'dbFieldType'} };
  if (!$isValidDbFieldType) {
    my $validDbFieldTypesAsCSV = join ", ", keys %validDbFieldTypes;
    push @errors, "Invalid value for 'Database Options > Stored As.  Valid options: $validDbFieldTypesAsCSV";
  }

  # don't allow more than one primary category
  my $primaryCategoryFieldnames     = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getArticleCategoryFieldnames('primary');
  my $firstPrimaryCategoryFieldname = $primaryCategoryFieldnames->[0];
  my $oldFieldName                  = $FORM->{'fieldName'};
  if ($firstPrimaryCategoryFieldname ne $oldFieldName) {
    push @errors, "You cannot have more than one 'Primary Category' field.";
  }

  #
  return @errors;
}

# ------------------------------------------------------------------------------
# Function    : getArticleCategoryFieldnames
# Description : primary categories are always sorted first in "all" list.
# Usage       : my $categoryFieldnames = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getArticleCategoryFieldnames($categoryFieldType);
# ------------------------------------------------------------------------------

sub getArticleCategoryFieldnames {
  my $fieldType = shift || die "no fieldtype specified!";
  my $tableName = "${TABLE_PREFIX}article";

  # error checking
  unless ($fieldType eq 'all' || $fieldType eq 'primary' || $fieldType eq 'secondary') {
    die "Invalid fieldType '$fieldType'.  Must be 'all', 'primary' or 'secondary'!\n";
  }

  # get fields
  my @categoryFields;
  my @sortedFieldNames = &IT::App::getUserSortedFieldNames($tableName);
  foreach my $fieldName (@sortedFieldNames) {
    my $appFieldType       = $IT::DB::Schema::FIELD_ATTRIBUTES->{$tableName}{$fieldName}{'appFieldType'};
    my $appCustomFieldType = $IT::DB::Schema::FIELD_ATTRIBUTES->{$tableName}{$fieldName}{'appCustomFieldType'};
    unless ($appFieldType eq 'custom') { next; }

    if ($appCustomFieldType eq 'articleEditorPrimaryCategory') {
      if ($fieldType eq 'all' || $fieldType eq 'primary') {
        unshift @categoryFields, $fieldName;   # add to start of list
      }
    }

    if ($appCustomFieldType eq 'articleEditorSecondaryCategory') {
      if ($fieldType eq 'all' || $fieldType eq 'secondary') {
        push @categoryFields, $fieldName;      # add to end of list
      }
    }
  }

  #
  return \@categoryFields;
}

# ------------------------------------------------------------------------------
# Function    : getArticleCategoryNums
# Description : primary category are always sorted first. returns
#               all defined values as array ref
# Usage       : my $categoryNums = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getArticleCategoryNums($article);
# ------------------------------------------------------------------------------

sub getArticleCategoryNums {
  my $article   = shift || die "no article record specified!";

  my $categoryNums = [];
  my $categoryFieldnames = &IT::ArtMan::CustomFields::ArticleEditor::PrimaryCategory::getArticleCategoryFieldnames('all');
  foreach my $fieldname (@$categoryFieldnames) {
    my $categoryNum = $article->{$fieldname};
    if ($categoryNum) {
      push @$categoryNums, $categoryNum;
    }
  }

  return $categoryNums;
}

# ----------------------------------------------------------------------------
# end of file
1;

