<commit_before>//
//  LBPhotoGalleryView.swift
//  LBPhotoGalleryExample
//
//  Created by <NAME> on 06/03/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import UIKit

enum LBPhotoGalleryMode
{
	case ImageLocal
	case ImageRemote
	case CustomView
}

enum LBPhotoCaptionStyle
{
	case PlainText
	case AttributedText
	case CustomView
}

enum LBPhotoGalleryDoubleTapHandler: Int
{
	case None = 0
	case Zoom = 1
	case Custom = 2
}

let DefaultSubviewsGap: CGFloat = 30.0
let MaxSpareViews = 1

class LBPhotoGalleryView: UIView, LBPhotoGalleryDelegate
{
	var mainScrollView: UIScrollView!
	
	var mainScrollIndicatorView: UIImageView!
	
	var reusableViews = [LBPhotoContainerView]()
	var dataSourceNumOfViews: Int = 0
	//var initialIndex: Int = 0
	var currentPage: Int = 0
	
	@IBOutlet var delegate: LBPhotoGalleryDelegate?
	@IBOutlet var dataSource: LBPhotoGalleryDataSource?
	
	override init(frame: CGRect)
	{
		super.init(frame: frame)
		
		self.autoresizingMask = .FlexibleTopMargin | .FlexibleLeftMargin | .FlexibleWidth | .FlexibleHeight
		
		self.initMainScrollView()
	}

	required init(coder aDecoder: NSCoder)
	{
		super.init(coder: aDecoder)
		
		self.autoresizingMask = .FlexibleTopMargin | .FlexibleLeftMargin | .FlexibleWidth | .FlexibleHeight;
		
		self.initMainScrollView()
	}
	
	override func awakeFromNib()
	{
		super.awakeFromNib()
		self.initMainScrollView()
		
	}
	
	override func layoutSubviews()
	{
		super.layoutSubviews()
		
		self.setupMainScrollView()
	}
	
	// MARK: - Public methods
	var galleryMode: LBPhotoGalleryMode = .ImageLocal
	{
		didSet {
			self.layoutSubviews()
		}
	}

	var captionStyle: LBPhotoCaptionStyle = .PlainText
	{
		didSet {
			self.layoutSubviews()
		}
	}
	
	var peakSubView: Bool = false
	{
		didSet {
			mainScrollView.clipsToBounds = peakSubView
		}
	}
	
	var showScrollIndicators: Bool = false
	{
		didSet {
			if showScrollIndicators {
				self.setupScrollIndicator()
			}
		}
	}
	
	var initialIndex: Int = 0
	
	var verticalGallery: Bool = false
	{
		didSet {
			updateSubviewsGap()
			currentPage = initialIndex
			
			self.scrollToPage(currentPage, animated:false)
		}
	}
	
	var subviewGap: CGFloat = 0
	{
		didSet {
			updateSubviewsGap()
		}
	}
	
	func updateSubviewsGap()
	{
		var frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)
		
		if verticalGallery {
			frame.size.height += subviewGap
		}
		else {
			frame.size.width += subviewGap
		}
		
		mainScrollView.frame = frame
		mainScrollView.contentSize = frame.size
	}
	
	/*func setInitialIndex(index: Int, animated: Bool)
	{
		initialIndex = index
		currentPage = index
		
		self.scrollToPage(currentPage, animated:animated)
	}*/
	
	func scrollToPage(page: Int, animated: Bool) -> Bool
	{
		if page < 0 || page >= dataSourceNumOfViews {
			return false
		}
		
		currentPage = page
		self.populateSubviews()
		
		var contentOffset = mainScrollView.contentOffset
		
		if verticalGallery {
			contentOffset.y = CGFloat(currentPage) * mainScrollView.frame.size.height
		}
		else {
			contentOffset.x = CGFloat(currentPage) * mainScrollView.frame.size.width
		}
		
		mainScrollView.setContentOffset(contentOffset, animated:animated)
		
		return true
	}
	
	func scrollToBesidePage(delta: Int, animated: Bool) -> Bool
	{
		return self.scrollToPage(currentPage + delta, animated: animated)
	}

	func getCurrentView() -> LBPhotoContainerView?
	{
		for view in mainScrollView.subviews {
			if view is LBPhotoContainerView && view.tag == currentPage {
				return (view as LBPhotoContainerView)
			}
		}
		
		return nil
	}
	
	
	// MARK: - UIScrollViewDelegate
	func scrollViewDidScroll(scrollView: UIScrollView)
	{
		var newPage: CGFloat
		var scrollIndicatorMoveSpace: CGFloat
		
		if verticalGallery {
			newPage = scrollView.contentOffset.y / scrollView.frame.size.height
		}
		else {
			newPage = scrollView.contentOffset.x / scrollView.frame.size.width
		}
		
		if let indicatorView = mainScrollIndicatorView {
			var frame = mainScrollIndicatorView.frame
			
			if verticalGallery {
				if dataSourceNumOfViews == 1 {
					scrollIndicatorMoveSpace = 0
				}
				else {
					scrollIndicatorMoveSpace = (self.frame.size.height - mainScrollIndicatorView.frame.size.height) / CGFloat(dataSourceNumOfViews - 1)
				}
				frame.origin.y = newPage * scrollIndicatorMoveSpace
			} else {
				if dataSourceNumOfViews == 1 {
					scrollIndicatorMoveSpace = 0
				}
				else {
					scrollIndicatorMoveSpace = (self.frame.size.width - mainScrollIndicatorView.frame.size.width) / CGFloat(dataSourceNumOfViews - 1)
				}
				frame.origin.x = newPage * scrollIndicatorMoveSpace
			}
			
			mainScrollIndicatorView.frame = frame
		}
		
		if Int(newPage) != currentPage {
			currentPage = Int(newPage)
			self.populateSubviews()
			
			for subView in reusableViews {
				if subView.tag != Int(newPage) {
					subView.resetZoom()
				}
			}
		}
		
		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewDidScroll:") {
			self.delegate!.scrollViewDidScroll!(scrollView)
		}
	}
	
	func scrollViewWillBeginDragging(scrollView: UIScrollView)
	{
		if let indicatorView = self.mainScrollIndicatorView {
			indicatorView.tag = 1
			UIView.animateWithDuration(0.3, animations: { () -> Void in
				indicatorView.alpha = 1
			})
		}

		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewWillBeginDragging:") {
			self.delegate!.scrollViewWillBeginDragging!(scrollView)
		}
	}
	
	func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
	{
		if !decelerate {
			self.scrollViewDidEndDecelerating(scrollView)
		}
		
		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewDidEndDragging:willDecelerate:") {<commit_msg>- images have their zoom value reset once they are no longer on the screen<commit_after>//
//  LBPhotoGalleryView.swift
//  LBPhotoGalleryExample
//
//  Created by <NAME> on 06/03/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import UIKit

enum LBPhotoGalleryMode
{
	case ImageLocal
	case ImageRemote
	case CustomView
}

enum LBPhotoCaptionStyle
{
	case PlainText
	case AttributedText
	case CustomView
}

enum LBPhotoGalleryDoubleTapHandler: Int
{
	case None = 0
	case Zoom = 1
	case Custom = 2
}

let DefaultSubviewsGap: CGFloat = 30.0
let MaxSpareViews = 1

class LBPhotoGalleryView: UIView, LBPhotoGalleryDelegate
{
	var mainScrollView: UIScrollView!
	
	var mainScrollIndicatorView: UIImageView!
	
	var reusableViews = [LBPhotoContainerView]()
	var dataSourceNumOfViews: Int = 0
	//var initialIndex: Int = 0
	var currentPage: Int = 0
	
	@IBOutlet var delegate: LBPhotoGalleryDelegate?
	@IBOutlet var dataSource: LBPhotoGalleryDataSource?
	
	override init(frame: CGRect)
	{
		super.init(frame: frame)
		
		self.autoresizingMask = .FlexibleTopMargin | .FlexibleLeftMargin | .FlexibleWidth | .FlexibleHeight
		
		self.initMainScrollView()
	}

	required init(coder aDecoder: NSCoder)
	{
		super.init(coder: aDecoder)
		
		self.autoresizingMask = .FlexibleTopMargin | .FlexibleLeftMargin | .FlexibleWidth | .FlexibleHeight;
		
		self.initMainScrollView()
	}
	
	override func awakeFromNib()
	{
		super.awakeFromNib()
		self.initMainScrollView()
		
	}
	
	override func layoutSubviews()
	{
		super.layoutSubviews()
		
		self.setupMainScrollView()
	}
	
	// MARK: - Public methods
	var galleryMode: LBPhotoGalleryMode = .ImageLocal
	{
		didSet {
			self.layoutSubviews()
		}
	}

	var captionStyle: LBPhotoCaptionStyle = .PlainText
	{
		didSet {
			self.layoutSubviews()
		}
	}
	
	var peakSubView: Bool = false
	{
		didSet {
			mainScrollView.clipsToBounds = peakSubView
		}
	}
	
	var showScrollIndicators: Bool = false
	{
		didSet {
			if showScrollIndicators {
				self.setupScrollIndicator()
			}
		}
	}
	
	var initialIndex: Int = 0
	
	var verticalGallery: Bool = false
	{
		didSet {
			updateSubviewsGap()
			currentPage = initialIndex
			
			self.scrollToPage(currentPage, animated:false)
		}
	}
	
	var subviewGap: CGFloat = 0
	{
		didSet {
			updateSubviewsGap()
		}
	}
	
	func updateSubviewsGap()
	{
		var frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)
		
		if verticalGallery {
			frame.size.height += subviewGap
		}
		else {
			frame.size.width += subviewGap
		}
		
		mainScrollView.frame = frame
		mainScrollView.contentSize = frame.size
	}
	
	/*func setInitialIndex(index: Int, animated: Bool)
	{
		initialIndex = index
		currentPage = index
		
		self.scrollToPage(currentPage, animated:animated)
	}*/
	
	func scrollToPage(page: Int, animated: Bool) -> Bool
	{
		if page < 0 || page >= dataSourceNumOfViews {
			return false
		}
		
		currentPage = page
		self.populateSubviews()
		
		var contentOffset = mainScrollView.contentOffset
		
		if verticalGallery {
			contentOffset.y = CGFloat(currentPage) * mainScrollView.frame.size.height
		}
		else {
			contentOffset.x = CGFloat(currentPage) * mainScrollView.frame.size.width
		}
		
		mainScrollView.setContentOffset(contentOffset, animated:animated)
		
		return true
	}
	
	func scrollToBesidePage(delta: Int, animated: Bool) -> Bool
	{
		return self.scrollToPage(currentPage + delta, animated: animated)
	}

	func getCurrentView() -> LBPhotoContainerView?
	{
		for view in mainScrollView.subviews {
			if view is LBPhotoContainerView && view.tag == currentPage {
				return (view as LBPhotoContainerView)
			}
		}
		
		return nil
	}
	
	
	// MARK: - UIScrollViewDelegate
	func scrollViewDidScroll(scrollView: UIScrollView)
	{
		var newPage: CGFloat
		var scrollIndicatorMoveSpace: CGFloat
		
		if verticalGallery {
			newPage = scrollView.contentOffset.y / scrollView.frame.size.height
		}
		else {
			newPage = scrollView.contentOffset.x / scrollView.frame.size.width
		}
		
		if let indicatorView = mainScrollIndicatorView {
			var frame = mainScrollIndicatorView.frame
			
			if verticalGallery {
				if dataSourceNumOfViews == 1 {
					scrollIndicatorMoveSpace = 0
				}
				else {
					scrollIndicatorMoveSpace = (self.frame.size.height - mainScrollIndicatorView.frame.size.height) / CGFloat(dataSourceNumOfViews - 1)
				}
				frame.origin.y = newPage * scrollIndicatorMoveSpace
			} else {
				if dataSourceNumOfViews == 1 {
					scrollIndicatorMoveSpace = 0
				}
				else {
					scrollIndicatorMoveSpace = (self.frame.size.width - mainScrollIndicatorView.frame.size.width) / CGFloat(dataSourceNumOfViews - 1)
				}
				frame.origin.x = newPage * scrollIndicatorMoveSpace
			}
			
			mainScrollIndicatorView.frame = frame
		}
		
		if Int(newPage) != currentPage {
			currentPage = Int(newPage)
			self.populateSubviews()
		}
		
		for subView in reusableViews {
			if verticalGallery {
				if	subView.frame.origin.y < mainScrollView.contentOffset.y - mainScrollView.frame.size.height ||
					subView.frame.origin.y > mainScrollView.contentOffset.y + mainScrollView.frame.size.height
				{
					subView.resetZoom()
				}

			}
			else {
				if	subView.frame.origin.x < mainScrollView.contentOffset.x - mainScrollView.frame.size.width ||
					subView.frame.origin.x > mainScrollView.contentOffset.x + mainScrollView.frame.size.width
				{
					subView.resetZoom()
				}
			}
		}
		
		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewDidScroll:") {
			self.delegate!.scrollViewDidScroll!(scrollView)
		}
	}
	
	func scrollViewWillBeginDragging(scrollView: UIScrollView)
	{
		if let indicatorView = self.mainScrollIndicatorView {
			indicatorView.tag = 1
			UIView.animateWithDuration(0.3, animations: { () -> Void in
				indicatorView.alpha = 1
			})
		}

		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewWillBeginDragging:") {
			self.delegate!.scrollViewWillBeginDragging!(scrollView)
		}
	}
	
	func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
	{
		if !decelerate {
			self.scrollViewDidEndDecelerating(scrollView)
		}
		
		if self.delegate != nil && self.delegate!.respondsToSelector("scrollViewDidEndDragging:willDecelerate:") {
{'fraction_non_alphanumeric': 0.09449148989687264, 'fraction_numerical': 0.005869036639557307, 'mean_word_length': 3.6000771307365986, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1443794', 'n_tokens_mistral': 4693, 'n_tokens_neox': 3924, 'n_words': 773}