using System;
using System.Collections.Generic;
using Valg.EVA.Skanning.Contracts.CommonEnums;

namespace Valg.EVA.Skanning.Scan.ReadSoftContracts.Model
{
    public class ScannableFieldType
    {
        private readonly FieldType fieldType;
        private readonly string fieldName;
        private readonly bool isRequired;
        private readonly string defaultNullValue;
        private readonly bool alwaysRequireValidation;
        private readonly ITreatIndexedFieldAsOneSpecification indexedFieldAsOneSpecification;

        public static readonly ScannableFieldType BallotID = new ScannableFieldType(FieldType.BallotID, "BallotID", true, defaultNullValue: string.Empty);

        public static readonly ScannableFieldType BallotNo = new ScannableFieldType(FieldType.BallotNo, "BallotNo", true, defaultNullValue: string.Empty);

        public static readonly ScannableFieldType Stamp = new ScannableFieldType(FieldType.Stamp, "Stamp", true, defaultNullValue: "0", alwaysRequireValidation: true, indexedFieldAsOneSpecification: new TreatStampIndexedFieldAsOneSpecification());

        public static readonly ScannableFieldType Candidate = new ScannableFieldType(FieldType.Candidate, "Candidate", false);

        public static readonly ScannableFieldType MarkIncr = new ScannableFieldType(FieldType.MarkIncr, "MarkIncr", false);

        public static readonly ScannableFieldType MarkDecr = new ScannableFieldType(FieldType.MarkDecr, "MarkDecr", false);

        public static readonly ScannableFieldType Ca_renumber = new ScannableFieldType(FieldType.Ca_renumber, "Ca_renumber", false);

        public static readonly ScannableFieldType Party_Write = new ScannableFieldType(FieldType.Party_Write, "Party_Write", false);

        public static readonly ScannableFieldType Ref_opt = new ScannableFieldType(FieldType.Ref_opt, "Ref_opt", false);

        public static readonly ScannableFieldType MultipleStamps = new ScannableFieldType(FieldType.Ref_single, "ref_single", false, alwaysRequireValidation: true);
        public static readonly ScannableFieldType AffiliationName = new ScannableFieldType(FieldType.AffiliationName, "AffiliationName", false, alwaysRequireValidation: true, defaultNullValue: String.Empty);
        public static readonly ScannableFieldType ContestName = new ScannableFieldType(FieldType.ContestName, "ContestName", false, alwaysRequireValidation: true, defaultNullValue: String.Empty);

        private ScannableFieldType(FieldType fieldType, string fieldName, bool isRequired, string defaultNullValue = null, bool alwaysRequireValidation = false,
            ITreatIndexedFieldAsOneSpecification indexedFieldAsOneSpecification = null)
        {
            this.fieldType = fieldType;
            this.fieldName = fieldName;
            this.isRequired = isRequired;
            this.defaultNullValue = defaultNullValue;
            this.alwaysRequireValidation = alwaysRequireValidation;
            this.indexedFieldAsOneSpecification = indexedFieldAsOneSpecification;
        }

        public FieldType FieldType
        {
            get { return fieldType; }
        }
        public string FieldName
        {
            get { return fieldName; }
        }

        public bool IsRequired
        {
            get { return isRequired; }
        }
        public string DefaultNullValue
        {
            get { return defaultNullValue; }
        }
        public bool AlwaysRequireValidation
        {
            get { return alwaysRequireValidation; }
        }

        public bool TreatAllIndexedFieldsAsOne { get { return indexedFieldAsOneSpecification != null; } }

        public ScannedField PickIndexedFieldToUse(List<ScannedField> fields)
        {
            return indexedFieldAsOneSpecification.SelectIndexedField(fields);
        }
    }
}
