/*
 * Copyright 2009 ZXing authors
 *
 * Licensed 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.
 */

using System.Collections.Generic;
using ZXing.Common;
using ZXing.QrCode.Internal;

namespace ZXing.Multi.QrCode.Internal
{
   /// <summary>
   /// <p>Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
   /// is rotated or skewed, or partially obscured.</p>
   ///
   /// <author>Sean Owen</author>
   /// <author>Hannes Erven</author>
   /// </summary>
   public sealed class MultiDetector : Detector
   {
      private static readonly DetectorResult[] EMPTY_DETECTOR_RESULTS = new DetectorResult[0];

      /// <summary>
      /// Initializes a new instance of the <see cref="MultiDetector"/> class.
      /// </summary>
      /// <param name="image">The image.</param>
      public MultiDetector(BitMatrix image)
         : base(image)
      {
      }

      /// <summary>
      /// Detects the multi.
      /// </summary>
      /// <param name="hints">The hints.</param>
      /// <returns></returns>
      public DetectorResult[] detectMulti(IDictionary<DecodeHintType, object> hints)
      {
         var image = Image;
         var resultPointCallback =
             hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null : (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
         var finder = new MultiFinderPatternFinder(image, resultPointCallback);
         var infos = finder.findMulti(hints);

         if (infos.Length == 0)
         {
            return EMPTY_DETECTOR_RESULTS;
         }

         var result = new List<DetectorResult>();
         foreach (FinderPatternInfo info in infos)
         {
            var oneResult = processFinderPatternInfo(info);
            if (oneResult != null)
               result.Add(oneResult);
         }
         if (result.Count == 0)
         {
            return EMPTY_DETECTOR_RESULTS;
         }
         else
         {
            return result.ToArray();
         }
      }
   }
}
